Add host-first environment contracts (Local vs CI vs Prod), deps-only compose, and the Profile → Portrait → deep-access mock payment slice with device identity and auto-migrate on API startup. Co-authored-by: Cursor <cursoragent@cursor.com>
49 lines
1.5 KiB
Markdown
49 lines
1.5 KiB
Markdown
# Database — Golden Rules
|
||
|
||
Schema source of truth for P1 tables: [domain/erd.md](domain/erd.md).
|
||
|
||
## Naming
|
||
|
||
- `snake_case` only for tables and columns.
|
||
- Forbidden prefixes: `tbl_`, `t_`.
|
||
|
||
## Required columns on business tables
|
||
|
||
```
|
||
id
|
||
created_at
|
||
updated_at
|
||
deleted_at
|
||
```
|
||
|
||
## Types
|
||
|
||
- Prefer bounded `varchar(n)`.
|
||
- `TEXT` only when necessary.
|
||
- Timestamps: `timestamptz`.
|
||
|
||
## Keys & indexes
|
||
|
||
- Every foreign key indexed.
|
||
- Unique business keys enforced with UNIQUE.
|
||
|
||
## Migration Rules(强制)
|
||
|
||
1. **Every schema change requires a migration** under `apps/api/migrations/`.
|
||
2. **Never** modify production (or shared) databases by hand (`ALTER TABLE` in psql as a substitute for migration).
|
||
3. **Migration files are immutable** after merge to `main` — fix forward with a new migration; do not rewrite history on shared branches.
|
||
4. **Destructive changes** (drop column/table, type narrowing) require an explicit rollback/forward strategy in the same change set (Down file or follow-up migration + note).
|
||
5. App code must not query columns that are not yet migrated.
|
||
6. Local apply: start API(auto-migrate)or documented migrate command in [commands.md](commands.md).
|
||
|
||
## Soft delete
|
||
|
||
- Default: set `deleted_at`; do not hard-delete user content in P1.
|
||
- Queries filter `deleted_at IS NULL` unless the task says otherwise.
|
||
|
||
## AI MUST NOT
|
||
|
||
- 「先改库再补 migration」
|
||
- 在 handler 里拼临时 DDL
|
||
- 发明未在 `domain.md` / `erd.md` 出现的表名(先改文档)
|