Skip to content

Commit 3a6d39a

Browse files
committed
Initial commit
0 parents  commit 3a6d39a

File tree

430 files changed

+94051
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

430 files changed

+94051
-0
lines changed

.cursor/rules/backend.mdc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
description:
3+
globs: docent_core/_db_service/**/*.py,docent_core/services/**/*.py
4+
alwaysApply: false
5+
---
6+
# Sessions and services
7+
8+
Application services should accept a DB session and required services. This way, transaction management is handled across services.
9+
10+
```
11+
class Service:
12+
def __init__(self, session: AsyncSession, ...services):
13+
self.session = session
14+
...
15+
```
16+
17+
In cases where services need to immediately commit results (e.g., computing searches), you can pass an additional writer_session_ctx factory:
18+
19+
```
20+
class DiffService:
21+
def __init__(
22+
self,
23+
session: AsyncSession,
24+
writer_session_ctx: Callable[[], AsyncContextManager[AsyncSession]],
25+
...services,
26+
):
27+
self.session = session
28+
self.writer_session_ctx = writer_session_ctx
29+
...
30+
```
31+
32+
Other notes:
33+
- Flushing and committing are the responsibility of the service *callers* (e.g., workers, HTTP handlers), not the service itself, except in rare cases.
34+
- Methods in services should accept SQLAlchemy model instances as input, *not* IDs. The caller is responsible for pulling the instance from the database and validating its existence. When used together with dependency injection, this also reduces calls to the database.
35+
- In services, make sure to distinguish variables pointing to SQLAlchemy model instances from Pydantic objects. Prefix variables pointing to SQLAlchemy model instances with `sq_`.
36+
37+
# Polling vs pushing
38+
39+
TODO(mengk)

.cursor/rules/frontend.mdc

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
description:
3+
globs: docent_core/_web/**/*.ts,docent_core/_web/**/*.tsx
4+
alwaysApply: false
5+
---
6+
# State management
7+
8+
- Use Redux slices in `app/store` to store frontend state
9+
- Use RTK queries in `app/api` to access the backend through APIs.
10+
- We're still migrating API calls from thunks to RTK queries. Do not change any existing thunks unless the user explicitly tells you to do a refactor. However, any new functionality should be implemented using the RTK pattern.
11+
12+
# Styling
13+
14+
## Padding, spacing, and height
15+
- For div containers, set padding and spacing to `3`, e.g., `p-3 space-y-3`
16+
17+
## Color System
18+
19+
**Base Layout Colors:**
20+
- `bg-background` - Main page/app background
21+
- `bg-secondary` - Secondary surfaces, sidebars, toolbars, panels
22+
- `border-border` - Standard borders and dividers
23+
24+
**Text Colors:**
25+
- `text-primary` - Headings, emphasis, important text
26+
- `text-muted-foreground` - Subheadings, captions, softer text
27+
- Prefer `text-muted-foreground` against `bg-background`, `text-primary` against colored surfaces
28+
29+
**Semantic Colors (use instead of generic destructive/success classes):**
30+
- **Blue**: `bg-blue-bg`, `border-blue-border`, `text-blue-text`, `bg-blue-muted` (hover states)
31+
- **Indigo**: `bg-indigo-bg`, `border-indigo-border`, `text-indigo-text`, `bg-indigo-muted` (search results, highlights)
32+
- **Green**: `bg-green-bg`, `border-green-border`, `text-green-text`, `bg-green-muted` (success, play buttons)
33+
- **Red**: `bg-red-bg`, `border-red-border`, `text-red-text`, `bg-red-muted` (errors, delete actions)
34+
- **Orange**: `bg-orange-bg`, `border-orange-border`, `text-orange-text` (warnings)
35+
- **Yellow**: `bg-yellow-bg`, `border-yellow-border`, `text-yellow-text`, `bg-yellow-muted`
36+
- **Purple**: `bg-purple-bg`, `border-purple-border`, `text-purple-text`
37+
38+
**Border Usage:**
39+
- Default borders use `--border` variable automatically
40+
- For contrasting borders, use `border-primary/20` or semantic colors
41+
- Focus rings: rarely used, `ring-ring` available if needed
42+
43+
**Hover States:**
44+
- Use `-muted` variants for subtle hover effects
45+
- For bright hover states, use low opacity `-text` variants (e.g., `hover:bg-red-text/10`)
46+
47+
## Color System Rules
48+
49+
1. **Never use arbitrary color values** - always use the defined color system
50+
2. **Use semantic colors over generic ones** - `text-red-text` not `text-destructive`
51+
3. **Maintain contrast** - `text-primary` on colored backgrounds, `text-muted-foreground` on neutral backgrounds
52+
4. **Follow the naming convention** - `bg-[color]-bg`, `border-[color]-border`, `text-[color]-text`
53+
5. **Check both light and dark modes** - all colors are defined for both themes in `globals.css`

.cursor/rules/local_setup.mdc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
alwaysApply: false
3+
---
4+
5+
See docs/self_hosting/self_host_docent.md for instructions on how to start the complete application. Use the **manual installation**, in which you can use Docker compose to start databases, but you must manually start each service. Use autoreload for the frontend. For the api server and worker, do **not** use autoreload; manually interrupt + restart the process after making a change.

.cursor/rules/schemas.mdc

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
description:
3+
globs: docent_core/_db_service/schemas/*.py,
4+
alwaysApply: false
5+
---
6+
7+
# Misc rules
8+
9+
- Always use `Mapped[T]` for type hints. This helps pyright understand the type of the column and raise type errors.
10+
11+
# SQLA table specification
12+
13+
## Foreign Keys and Relationships
14+
15+
### Rule: Relationship Configuration
16+
Configure relationships with proper back-references and cascading:
17+
18+
```python
19+
# Parent side
20+
instances: Mapped[list["SQLADiffInstance"]] = relationship(
21+
"SQLADiffInstance",
22+
back_populates="result",
23+
cascade="all, delete-orphan",
24+
)
25+
26+
# Child side
27+
result: Mapped["SQLADiffResult"] = relationship(
28+
"SQLADiffResult",
29+
back_populates="instances",
30+
)
31+
```
32+
33+
**Key requirements**:
34+
- Use `Mapped[...]` type hints
35+
- Always specify `back_populates` for bidirectional relationships
36+
- Use `cascade="all, delete-orphan"` for parent-child relationships
37+
- Quote class names in relationships to handle forward references
38+
39+
### Rule: Cascade Behavior
40+
Use `cascade="all, delete-orphan"` for parent-child relationships where:
41+
- Children should be deleted when parent is deleted
42+
- Children cannot exist without a parent
43+
44+
**Example**: When a `DiffResult` is deleted, all its `DiffInstance` records should be deleted.
45+
46+
## Column Specifications
47+
48+
### Rule: Explicit Nullable Specification
49+
Always explicitly specify nullable behavior:
50+
51+
```python
52+
summary = mapped_column(Text, nullable=False)
53+
focus = mapped_column(Text, nullable=True)
54+
```
55+
56+
**Why**: Makes intent clear and prevents SQLAlchemy defaults from causing confusion.
57+
58+
### Rule: Use Appropriate Column Types
59+
- `String(36)` for UUIDs
60+
- `Text` for long text content
61+
- `JSONB` for complex data structures
62+
- `Boolean` for true/false values
63+
64+
### Rule: Index Foreign Keys
65+
Always add indexes to foreign key columns:
66+
67+
```python
68+
collection_id = mapped_column(
69+
String(36), ForeignKey(f"{TABLE_COLLECTION}.id"), nullable=False, index=True
70+
)
71+
```
72+
73+
**Why**: Foreign keys are frequently used in JOINs and WHERE clauses.
74+
75+
## Pydantic Integration
76+
77+
### Rule: Implement Conversion Methods
78+
Every SQLAlchemy model must implement both conversion methods:
79+
80+
```python
81+
@classmethod
82+
def from_pydantic(cls, model: PydanticModel, additional_params: str) -> "SQLAModel":
83+
"""Convert Pydantic model to SQLAlchemy model"""
84+
return cls(
85+
id=model.id,
86+
# ... other fields
87+
)
88+
89+
def to_pydantic(self) -> PydanticModel:
90+
"""Convert SQLAlchemy model to Pydantic model"""
91+
return PydanticModel(
92+
id=self.id,
93+
# ... other fields
94+
)
95+
```
96+
97+
### Rule: Handle Nested Relationships in Conversion
98+
When converting models with relationships, handle nested objects properly:
99+
100+
```python
101+
@classmethod
102+
def from_pydantic(cls, diff_result: DiffResult, query_id: str) -> "SQLADiffResult":
103+
sqla_instances = (
104+
[
105+
SQLADiffInstance.from_pydantic(instance, diff_result.id)
106+
for instance in diff_result.instances
107+
]
108+
if diff_result.instances is not None
109+
else []
110+
)
111+
return cls(
112+
id=diff_result.id,
113+
instances=sqla_instances,
114+
# ... other fields
115+
)
116+
```

0 commit comments

Comments
 (0)