feat(database): add initial schema and migrations for Company, Employ…#7
feat(database): add initial schema and migrations for Company, Employ…#7EDGUR-DEVELOPER wants to merge 1 commit intoLIDR-academy:mainfrom
Conversation
…ee, Position, InterviewFlow, InterviewType, InterviewStep, Candidate, Application, and Interview models fix(frontend): update caniuse-lite version in package-lock.json chore(migrations): create migration SQL for new database schema docs(ERD): add ERD diagram for the new database structure docs(prompts): create prompts for ER analysis and database optimization
WalkthroughThis PR introduces a comprehensive database schema for a recruitment and HR workflow system. It creates 12 interconnected Prisma models (Company, Employee, Position, InterviewFlow, InterviewType, InterviewStep, Candidate, Education, WorkExperience, Resume, Application, Interview), establishes their relationships with appropriate cascading deletes, and includes corresponding SQL migration and ER documentation files. Changes
Sequence Diagram(s)sequenceDiagram
participant Company
participant Employee
participant Position
participant InterviewFlow
participant InterviewStep
participant Candidate
participant Application
participant Interview
Candidate->>Application: submits
Application->>Position: applies for
Position->>Company: belongs to
Position->>InterviewFlow: has
InterviewFlow->>InterviewStep: contains
Interview->>InterviewStep: scheduled for
Interview->>Candidate: involves
Interview->>Employee: conducted by
Employee->>Company: works for
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Areas requiring attention:
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
backend/prisma/schema.prisma (1)
74-114: Consider makingInterviewFlow.namenon-nullable for operational clarity.Line 76 defines
nameas optional forInterviewFlow. Since named flows are central to workflow management, requiring a name would prevent accidentally creating unnamed flows. Additionally,InterviewStep.orderIndex(line 102) should ideally be non-nullable with a unique constraint per flow to enforce deterministic ordering.model InterviewFlow { id Int @id @default(autoincrement()) - name String? @db.VarChar(150) + name String @db.VarChar(150) description String? @db.Text isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt positions Position[] steps InterviewStep[] }For
InterviewStep, consider adding a unique constraint on(interviewFlowId, orderIndex):model InterviewStep { id Int @id @default(autoincrement()) interviewFlowId Int interviewTypeId Int - name String @db.VarChar(150) - orderIndex Int? + name String @db.VarChar(150) + orderIndex Int description String? @db.Text durationMinutes Int? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt interviewFlow InterviewFlow @relation(fields: [interviewFlowId], references: [id], onDelete: Restrict) interviewType InterviewType @relation(fields: [interviewTypeId], references: [id], onDelete: Restrict) interviews Interview[] @@index([interviewFlowId]) @@index([interviewTypeId]) + @@unique([interviewFlowId, orderIndex]) }backend/prisma/migrations/20251116230729_/migration.sql (1)
172-221: Indexes and foreign keys properly designed; one redundant index flagged.The migration file has comprehensive index coverage on all foreign keys and a well-considered composite index on Application(positionId, status) for efficient workflow queries. However, line 194 creates a redundant index on Candidate.email since line 191 already creates a UNIQUE INDEX on the same column. UNIQUE constraints automatically create indexes.
-- CreateIndex CREATE UNIQUE INDEX "Candidate_email_key" ON "Candidate"("email"); -- CreateIndex - CREATE INDEX "Candidate_email_idx" ON "Candidate"("email");Similarly, remove the redundant index from the Prisma schema at
backend/prisma/schema.prismaline 131.prompts/prompts-EGR.md (2)
1-112: ℹ️ Minor: Spanish grammar and Markdown formatting issues flagged by static analysis.The three prompts are well-structured for AI-assisted database analysis and optimization. Static analysis tools flagged several minor issues:
Spanish Grammar (optional fixes):
- Line 1: "Inicial" → "inicial" (lowercase)
- Line 30: "Llaves" → "llaves" (lowercase)
- Line 51: "Indices" → "índices" (accented), and "la base datos" → "la base de datos"
Markdown Formatting (optional fixes):
- Line 31: Table should have blank line before it
- Line 96: Code block should specify language identifier:
```prismaThese are cosmetic issues that don't affect functionality; addressing them would improve consistency with Spanish language conventions and Markdown best practices.
205-227: Note: Prompt 3 suggests enum types for status fields, but current schema uses String.Prompt 3's embedded Mermaid diagram (lines 205-227) annotates status fields as
enumtypes:
- Line 210: Application.status shown as
enum status- Line 222: Interview.result shown as
enum resultHowever, the current schema.prisma uses String types for these fields (lines 175, 195). Using Prisma enums would provide better type safety and domain constraint enforcement:
enum ApplicationStatus { SUBMITTED REVIEWING REJECTED ACCEPTED // ... etc } model Application { // ... status ApplicationStatus? @db.VarChar(50) // ... }This is a design suggestion for future refinement; the current String approach is flexible but less typesafe.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
backend/package-lock.jsonis excluded by!**/package-lock.jsonfrontend/package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (4)
backend/prisma/migrations/20251116230729_/migration.sql(1 hunks)backend/prisma/schema.prisma(4 hunks)prompts/ERD.md(1 hunks)prompts/prompts-EGR.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
prompts/prompts-EGR.md
[grammar] ~1-~1: Corrige la mayúscula.
Context: ## Prompt 1: Prompt Inicial para el analisis del diseño ER Actúa co...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_ORTHOGRAPHY_UPPERCASE)
[grammar] ~13-~13: Cambia la palabra o signo.
Context: ...) 3. Analiza todas las relaciones entre entidades: - Tipo de relación (1:1, 1:N, N:N) - Di...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_PUNCTUATION)
[grammar] ~30-~30: Corrige la mayúscula.
Context: ...K y FK especificados) #### 2. Tabla de Llaves | Entidad | PK | FK | Descripción FK | ...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_ORTHOGRAPHY_UPPERCASE)
[grammar] ~51-~51: Cambia la forma del sustantivo.
Context: ...a de base de datos con la definición de Indices y la normalización de la base datos Act...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_NOUN_FORM)
[grammar] ~51-~51: Aquí puede haber un error.
Context: ...ión de Indices y la normalización de la base datos Actúa como un arquitecto de bases...
(QB_NEW_ES)
[grammar] ~51-~51: Se encontraron 2 posibles errores
Context: ...e Indices y la normalización de la base datos Actúa como un arquitecto de bases de da...
(QB_NEW_ES_OTHER_ERROR_IDS_MERGED_MATCHES___MISSING_ADPOSITION___MISSING_PUNCTUATION)
[grammar] ~53-~53: Agrega un signo de puntuación.
Context: ... diseño físico. Del análisis previo que realizaste incluye: - Lista de entidades - Atribut...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~78-~78: Agrega un signo de puntuación.
Context: ...plimiento de 1FN, 2FN, 3FN y BCNF si es necesario - Explica cada corrección o decisión...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~79-~79: Agrega un signo de puntuación.
Context: ...ecesario - Explica cada corrección o decisión - Indica qué entidades o atributos f...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~80-~80: Aquí puede haber un error.
Context: ...butos fueron modificados para normalizar 4. Diseña el modelo lógico final: - ...
(QB_NEW_ES)
[grammar] ~92-~92: Aquí puede haber un error.
Context: ... particionamiento o clustering si aplica ### Formato de salida requerido: Devuelve la...
(QB_NEW_ES)
[grammar] ~95-~95: Agrega un signo de puntuación.
Context: ...: Devuelve la información en estructura .prisma Ejemplo: ``` model WorkExperience { i...
(QB_NEW_ES_OTHER_ERROR_IDS_MISSING_PUNCTUATION)
[grammar] ~112-~112: Aquí puede haber un error.
Context: ...generar SQL DDL; solo estructura .prisma ## Prompt 3: Agregando la nueva estructura ...
(QB_NEW_ES)
[grammar] ~115-~115: Corrige la minúscula.
Context: ...l archivo schema.prisma Como experto en prisma, adapta estos nuevos cambios con la inf...
(QB_NEW_ES_OTHER_ERROR_IDS_REPLACEMENT_ORTHOGRAPHY_LOWERCASE)
🪛 markdownlint-cli2 (0.18.1)
prompts/prompts-EGR.md
31-31: Tables should be surrounded by blank lines
(MD058, blanks-around-tables)
96-96: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (4)
backend/prisma/schema.prisma (3)
16-72: ✅ Well-structured entity models with appropriate constraints.Company, Employee, and Position models are well-designed with proper field types, unique constraints on email, and thoughtful cascading/restrict delete policies.
116-168: ✅ Candidate profile models well-designed with proper cascade delete semantics.The Candidate model and its related Education, WorkExperience, and Resume models are appropriately structured with:
- Cascade delete for dependent records (Education, WorkExperience, Resume) so deleting a candidate cleans up associated data
- Separate firstName/lastName fields supporting international naming conventions
- Unique email constraint with supporting index for efficient lookups
- Proper timestamp management
One note: Resume stores file metadata (path, type) rather than binary data, which is a scalability best practice for file handling.
170-208: ✅ Application and Interview models capture recruitment workflow with excellent indexing.Both models properly represent the core workflow:
- Application bridges candidates and positions with status tracking
- Interview captures actual interview details with multiple outcome states
- Composite index on (positionId, status) supports efficient recruitment dashboard queries
- All foreign keys use Restrict delete, preventing orphaned records
- Optional fields (interviewDate, result, score) allow progressive record completion through the hiring workflow
backend/prisma/migrations/20251116230729_/migration.sql (1)
1-170: ✅ Migration properly implements schema with appropriate cascading delete patterns.The SQL migration file correctly materializes the Prisma schema with all 12 tables, proper foreign key constraints, and well-considered cascading behaviors:
- Cascade delete for dependent records (Education, WorkExperience, Resume tied to Candidate)
- Restrict delete for core entities to prevent accidental orphaning
- SetNull for optional relationships (Position.interviewFlowId)
All field types, constraints, and relationships align with the Prisma schema.
| datasource db { | ||
| provider = "postgresql" | ||
| url = env("DATABASE_URL") | ||
| url = "postgresql://LTIdbUser:D1ymf8wyQEGthFR1E9xhCq@localhost:5432/LTIdb" | ||
| } |
There was a problem hiding this comment.
🔴 CRITICAL SECURITY ISSUE: Hardcoded database credentials exposed.
The datasource URL contains database credentials embedded directly in the schema file, which will be permanently stored in version control history and accessible to anyone with repository access.
Replace the hardcoded URL with an environment variable:
datasource db {
provider = "postgresql"
- url = "postgresql://LTIdbUser:D1ymf8wyQEGthFR1E9xhCq@localhost:5432/LTIdb"
+ url = env("DATABASE_URL")
}Then ensure DATABASE_URL is configured in your .env file (which should be .gitignore'd). If this commit has already been pushed, you must:
- Revoke the exposed credentials immediately
- Rotate the database password
- Force-push this fix to remove credentials from history, or contact your security team
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| datasource db { | |
| provider = "postgresql" | |
| url = env("DATABASE_URL") | |
| url = "postgresql://LTIdbUser:D1ymf8wyQEGthFR1E9xhCq@localhost:5432/LTIdb" | |
| } | |
| datasource db { | |
| provider = "postgresql" | |
| url = env("DATABASE_URL") | |
| } |
🤖 Prompt for AI Agents
In backend/prisma/schema.prisma around lines 12 to 15, the datasource URL
currently contains hardcoded DB credentials; replace the literal URL with an
environment variable reference (use env("DATABASE_URL")), add a local .env file
containing the DATABASE_URL value, ensure .env is listed in .gitignore, and if
the credentials were already pushed revoke and rotate the exposed password and
remove secrets from history (force-push or follow your security team's
remediation steps).
| ```mermaid | ||
| erDiagram | ||
|
|
||
| COMPANY { | ||
| int id PK | ||
| string name | ||
| } | ||
|
|
||
| EMPLOYEE { | ||
| int id PK | ||
| int company_id FK | ||
| string name | ||
| string email | ||
| string role | ||
| boolean is_active | ||
| } | ||
|
|
||
| POSITION { | ||
| int id PK | ||
| int company_id FK | ||
| int interview_flow_id FK | ||
| string title | ||
| text description | ||
| string status | ||
| boolean is_visible | ||
| string location | ||
| text job_description | ||
| text requirements | ||
| text responsibilities | ||
| numeric salary_min | ||
| numeric salary_max | ||
| string employment_type | ||
| text benefits | ||
| text company_description | ||
| date application_deadline | ||
| string contact_info | ||
| } | ||
|
|
||
| INTERVIEW_FLOW { | ||
| int id PK | ||
| string description | ||
| } | ||
|
|
||
| INTERVIEW_STEP { | ||
| int id PK | ||
| int interview_flow_id FK | ||
| int interview_type_id FK | ||
| string name | ||
| int order_index | ||
| } | ||
|
|
||
| INTERVIEW_TYPE { | ||
| int id PK | ||
| string name | ||
| text description | ||
| } | ||
|
|
||
| CANDIDATE { | ||
| int id PK | ||
| string firstName | ||
| string lastName | ||
| string email | ||
| string phone | ||
| string address | ||
| } | ||
|
|
||
| APPLICATION { | ||
| int id PK | ||
| int position_id FK | ||
| int candidate_id FK | ||
| date application_date | ||
| string status | ||
| text notes | ||
| } | ||
|
|
||
| INTERVIEW { | ||
| int id PK | ||
| int application_id FK | ||
| int interview_step_id FK | ||
| int employee_id FK | ||
| date interview_date | ||
| string result | ||
| int score | ||
| text notes | ||
| } | ||
|
|
||
| COMPANY ||--o{ EMPLOYEE : employs | ||
| COMPANY ||--o{ POSITION : offers | ||
| POSITION ||--|| INTERVIEW_FLOW : assigns | ||
| INTERVIEW_FLOW ||--o{ INTERVIEW_STEP : contains | ||
| INTERVIEW_STEP ||--|| INTERVIEW_TYPE : uses | ||
| POSITION ||--o{ APPLICATION : receives | ||
| CANDIDATE ||--o{ APPLICATION : submits | ||
| APPLICATION ||--o{ INTERVIEW : has | ||
| INTERVIEW ||--|| INTERVIEW_STEP : consists_of | ||
| EMPLOYEE ||--o{ INTERVIEW : conducts | ||
| ``` No newline at end of file |
There was a problem hiding this comment.
The Mermaid ERD is missing three important entities present in the Prisma schema and migration file:
- EDUCATION – Candidate's educational background (currently in schema)
- WORKEXPERIENCE – Candidate's work history (currently in schema)
- RESUME – Candidate's resume file metadata (currently in schema)
Additionally, line 89 defines the relationship POSITION ||--|| INTERVIEW_FLOW but Position.interviewFlowId is nullable in the schema, so the cardinality should reflect optional assignment:
- POSITION ||--|| INTERVIEW_FLOW : assigns
+ POSITION ||--o| INTERVIEW_FLOW : assignsUpdate the ERD to include these missing entities and their relationships:
+ EDUCATION {
+ int id PK
+ int candidate_id FK
+ string institution
+ string title
+ date startDate
+ date endDate
+ }
+
+ WORKEXPERIENCE {
+ int id PK
+ int candidate_id FK
+ string company
+ string position
+ text description
+ date startDate
+ date endDate
+ }
+
+ RESUME {
+ int id PK
+ int candidate_id FK
+ string filePath
+ string fileType
+ date uploadDate
+ }
CANDIDATE ||--o{ APPLICATION : submits
+ CANDIDATE ||--o{ EDUCATION : has
+ CANDIDATE ||--o{ WORKEXPERIENCE : has
+ CANDIDATE ||--o{ RESUME : hasCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In prompts/ERD.md around lines 1–97, the Mermaid ERD is missing three schema
entities (EDUCATION, WORKEXPERIENCE, RESUME) and the cardinality between
POSITION and INTERVIEW_FLOW is incorrect for a nullable FK; add EDUCATION,
WORKEXPERIENCE and RESUME entities with id PK and candidate_id FK (and include
relevant schema fields like degree/school for EDUCATION, company/role/dates for
WORKEXPERIENCE, and file metadata for RESUME), connect each to CANDIDATE with
CANDIDATE ||--o{ EDUCATION, CANDIDATE ||--o{ WORKEXPERIENCE and CANDIDATE ||--o{
RESUME, and change the POSITION–INTERVIEW_FLOW relationship to reflect an
optional interview_flow_id (use the Mermaid cardinality syntax for optional on
the POSITION side instead of the current required ||--||).
💪 Fortalezas
🛠 Recomendaciones
✨ Mensaje finalMuy buen trabajo, se nota que entendiste tanto la parte de modelado como la integración con Prisma. Con un par de |
…ee, Position, InterviewFlow, InterviewType, InterviewStep, Candidate, Application, and Interview models
fix(frontend): update caniuse-lite version in package-lock.json
chore(migrations): create migration SQL for new database schema
docs(ERD): add ERD diagram for the new database structure
docs(prompts): create prompts for ER analysis and database optimization
Summary by CodeRabbit
Release Notes
New Features
Documentation