You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+11-1Lines changed: 11 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,10 +12,19 @@ Any future automated changes (by tools or agents) must respect these rules.
12
12
-`(admin)` for the admin interface.
13
13
- Data access is via **Drizzle ORM** (`src/server/db.ts`, `src/server/db/schema.ts`) against PostgreSQL with migrations driven by `drizzle.config.ts` and the `drizzle/` directory.
14
14
- Application data and metadata shapes live in `src/types/application-data.ts`; prefer these shared `ApplicationData`, `ApplicationMeta`, and `NormalizedApplication` aliases whenever you read or write applicant records so the loose JSON payloads remain typed.
15
-
- Application rows now store data and meta in dedicated columns (no JSON `data`/`meta` fields):
15
+
- Application rows now store data and meta in dedicated columns (no JSON `data`/`meta` fields), and IDs are generated with **cuid2** (`@paralleldrive/cuid2`):
- Meta columns: `meta_invited_statuses`, `meta_document_statuses`, `meta_document_comments`.
18
18
- Always convert between DB rows and typed shapes via `src/server/application-normalizer.ts` (`buildApplicationData`, `buildApplicationMeta`, `mapApplicationDataToColumns`); do not reintroduce JSON blobs.
19
+
- Application relations are normalized (all PKs use cuid2 defaults):
20
+
-`application_program_choice`: program selection, rank, campus/start term/study mode/funding.
21
+
-`application_education`: education entries by type (GCE_OL, GCE_AL, BAC, PROBATOIRE, BTS, BACHELOR, OTHER), with session year, candidate number, status, dates, GPA, etc.
22
+
-`application_document`: per-document rows with kind, status, reviewer comment; can link to an education row.
23
+
-`application_phone`: per phone with kind (PRIMARY/SECONDARY/GUARDIAN/OTHER) and call flags.
24
+
-`application_consent`: per-consent records.
25
+
-`application_status_history`: status transitions with actor.
26
+
- Applicant edit guardrails: applicants may update only when status is `INIT` or `NEED_APPLICANT_INTERVENTION`; other statuses forbid applicant-side updates.
27
+
- Application status enum includes `NEED_APPLICANT_INTERVENTION` (surface this in UI/status mapping).
19
28
-**tRPC** is the single backend API surface:
20
29
- Server router at `src/server/api/*` and `src/app/api/trpc/[trpc]/route.ts`.
21
30
- Shared tRPC clients:
@@ -105,4 +114,5 @@ These conventions must be followed for all new or modified code:
105
114
## Database & Migrations
106
115
107
116
- Drizzle migrations live in `drizzle/`; the current migration splitting application JSON fields is `drizzle/0000_expand_application_fields.sql` with journal tracking under `drizzle/meta/_journal.json`.
117
+
- Drizzle migration `0001_application_relations.sql` adds the normalized relations above and the new status; journal tracked in `drizzle/meta/_journal.json`.
108
118
- Migrations runner container is defined at `companions/migrations/Dockerfile` and `companions/migrations/entrypoint.sh`; it uses `yarn drizzle-kit migrate` (no Prisma) and requires `DATABASE_URL` at runtime. Build with `docker build -f companions/migrations/Dockerfile -t gis-migrations .` and run with `docker run --rm -e DATABASE_URL=... gis-migrations`.
ALTERTABLE"account" ADD CONSTRAINT"account_user_id_user_id_fk"FOREIGN KEY ("user_id") REFERENCES"public"."user"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
165
+
ALTERTABLE"application_consent" ADD CONSTRAINT"application_consent_application_id_application_id_fk"FOREIGN KEY ("application_id") REFERENCES"public"."application"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
166
+
ALTERTABLE"application_document" ADD CONSTRAINT"application_document_application_id_application_id_fk"FOREIGN KEY ("application_id") REFERENCES"public"."application"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
167
+
ALTERTABLE"application_document" ADD CONSTRAINT"application_document_education_id_application_education_id_fk"FOREIGN KEY ("education_id") REFERENCES"public"."application_education"("id") ON DELETEsetnullONUPDATE no action;--> statement-breakpoint
168
+
ALTERTABLE"application_education" ADD CONSTRAINT"application_education_application_id_application_id_fk"FOREIGN KEY ("application_id") REFERENCES"public"."application"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
169
+
ALTERTABLE"application_phone" ADD CONSTRAINT"application_phone_application_id_application_id_fk"FOREIGN KEY ("application_id") REFERENCES"public"."application"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
170
+
ALTERTABLE"application_program_choice" ADD CONSTRAINT"application_program_choice_application_id_application_id_fk"FOREIGN KEY ("application_id") REFERENCES"public"."application"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
171
+
ALTERTABLE"application_status_history" ADD CONSTRAINT"application_status_history_application_id_application_id_fk"FOREIGN KEY ("application_id") REFERENCES"public"."application"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
172
+
ALTERTABLE"application_status_history" ADD CONSTRAINT"application_status_history_changed_by_id_user_id_fk"FOREIGN KEY ("changed_by_id") REFERENCES"public"."user"("id") ON DELETEsetnullONUPDATE no action;--> statement-breakpoint
173
+
ALTERTABLE"application" ADD CONSTRAINT"application_createdById_user_id_fk"FOREIGN KEY ("createdById") REFERENCES"public"."user"("id") ON DELETE no action ONUPDATE no action;--> statement-breakpoint
174
+
ALTERTABLE"session" ADD CONSTRAINT"session_user_id_user_id_fk"FOREIGN KEY ("user_id") REFERENCES"public"."user"("id") ON DELETE cascadeONUPDATE no action;--> statement-breakpoint
175
+
CREATEINDEX "account_userId_idx" ON"account" USING btree ("user_id");--> statement-breakpoint
176
+
CREATEINDEX "application_consent_application_idx" ON"application_consent" USING btree ("application_id");--> statement-breakpoint
177
+
CREATEINDEX "application_document_application_idx" ON"application_document" USING btree ("application_id");--> statement-breakpoint
178
+
CREATEINDEX "application_document_education_idx" ON"application_document" USING btree ("education_id");--> statement-breakpoint
179
+
CREATEINDEX "application_document_status_idx" ON"application_document" USING btree ("status");--> statement-breakpoint
180
+
CREATEINDEX "application_document_kind_idx" ON"application_document" USING btree ("kind");--> statement-breakpoint
181
+
CREATEINDEX "application_education_application_idx" ON"application_education" USING btree ("application_id");--> statement-breakpoint
182
+
CREATEINDEX "application_education_type_idx" ON"application_education" USING btree ("type");--> statement-breakpoint
183
+
CREATEINDEX "application_phone_application_idx" ON"application_phone" USING btree ("application_id");--> statement-breakpoint
184
+
CREATEINDEX "application_program_choice_application_idx" ON"application_program_choice" USING btree ("application_id");--> statement-breakpoint
185
+
CREATEINDEX "application_status_history_application_idx" ON"application_status_history" USING btree ("application_id");--> statement-breakpoint
186
+
CREATEINDEX "application_created_by_id_idx" ON"application" USING btree ("createdById");--> statement-breakpoint
187
+
CREATEINDEX "session_userId_idx" ON"session" USING btree ("user_id");--> statement-breakpoint
188
+
CREATEINDEX "verification_identifier_idx" ON"verification" USING btree ("identifier");
0 commit comments