Skip to content

feat(database): add initial schema and migrations for Company, Employ…#7

Open
EDGUR-DEVELOPER wants to merge 1 commit intoLIDR-academy:mainfrom
EDGUR-DEVELOPER:db-EGR
Open

feat(database): add initial schema and migrations for Company, Employ…#7
EDGUR-DEVELOPER wants to merge 1 commit intoLIDR-academy:mainfrom
EDGUR-DEVELOPER:db-EGR

Conversation

@EDGUR-DEVELOPER
Copy link

@EDGUR-DEVELOPER EDGUR-DEVELOPER commented Nov 16, 2025

…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

    • Database infrastructure expanded to support comprehensive organizational and recruitment data management, including multi-entity structure, position management, structured interview workflows, candidate profiles, educational and professional backgrounds, and application tracking.
  • Documentation

    • Added database architecture diagrams and analysis tools for system design reference.

…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
@coderabbitai
Copy link

coderabbitai bot commented Nov 16, 2025

Walkthrough

This 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

Cohort / File(s) Summary
Database Schema Definition
backend/prisma/schema.prisma
Expanded Prisma schema with 12 new models representing recruitment workflow entities. Added Company, Employee, Position, InterviewFlow, InterviewType, InterviewStep, Candidate, Education, WorkExperience, Resume, Application, and Interview models with comprehensive relationships, indexes on foreign keys, and cascade delete behaviors. Updated datasource to hardcoded PostgreSQL connection string.
Database Migration
backend/prisma/migrations/20251116230729_/migration.sql
SQL migration creating all tables corresponding to the new Prisma schema, including primary keys, timestamps, domain-specific fields, indexes (with unique constraints on Employee.email and Candidate.email), and foreign key relationships with referential integrity enforcement.
Documentation & Analysis Prompts
prompts/ERD.md, prompts/prompts-EGR.md
Added Mermaid ER diagram documenting all entities and relationships using Crow's Foot notation. Added structured prompts for ER diagram analysis, database design optimization, and Prisma schema adaptation.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring attention:

  • Hardcoded database URL in schema.prisma (security consideration—should use environment variable)
  • Cascade delete behavior across relationships (verify all cascades are intentional, particularly for Candidate→Application→Interview chains)
  • Unique constraints on Employee.email and Candidate.email (ensure no duplicates in seed data or existing records)
  • Foreign key relationship consistency between SQL migration and Prisma schema (verify all relations match)
  • Index coverage on frequently queried relationships (confirm indexes support expected query patterns)

Poem

🐰 A warren of workflows, now organized neat,
Companies, roles, and candidates all meet,
Interviews cascade through relational bliss,
Database design—we couldn't resist!
From application to interview's call,
This schema's recruitment, ladder and all! 🎯

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding initial schema and migrations for recruitment/HR database models (Company, Employee, Position, InterviewFlow, InterviewType, InterviewStep, Candidate, Education, WorkExperience, Resume, Application, Interview).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

  • Provide custom instructions to shape the summary (bullet lists, tables, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example:

"Create a concise high-level summary as a bullet-point list. Then include a Markdown table showing lines added and removed by each contributing author."


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
backend/prisma/schema.prisma (1)

74-114: Consider making InterviewFlow.name non-nullable for operational clarity.

Line 76 defines name as optional for InterviewFlow. 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.prisma line 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: ```prisma

These 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 enum types:

  • Line 210: Application.status shown as enum status
  • Line 222: Interview.result shown as enum result

However, 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

📥 Commits

Reviewing files that changed from the base of the PR and between eba3f29 and c42395e.

⛔ Files ignored due to path filters (2)
  • backend/package-lock.json is excluded by !**/package-lock.json
  • frontend/package-lock.json is 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.

Comment on lines 12 to +15
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
url = "postgresql://LTIdbUser:D1ymf8wyQEGthFR1E9xhCq@localhost:5432/LTIdb"
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🔴 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:

  1. Revoke the exposed credentials immediately
  2. Rotate the database password
  3. 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.

Suggested change
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).

Comment on lines +1 to +97
```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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

⚠️ ERD diagram incomplete: missing three entities and one cardinality issue.

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 : assigns

Update 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 : has

Committable 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 ||--||).

@PetraZeta
Copy link
Contributor

💪 Fortalezas

  • El modelado de entidades (Company, Position, Candidate, Application, Interview, etc.) está muy bien estructurado y refleja de forma clara el flujo de negocio de un Talent Tracking System real.

  • Has cuidado la integridad referencial con FKs y reglas de borrado coherentes (RESTRICT en entidades core y CASCADE en historiales del candidato), lo que demuestra criterio de DBA.

  • La coherencia entre el script SQL y el schema.prisma es excelente: tipos, índices, relaciones y opciones de onDelete están perfectamente alineados.


🛠 Recomendaciones

  • Añade algunas restricciones de negocio adicionales
    Ejemplos:

    • CHECK (salaryMin <= salaryMax)
    • Unicidad de (positionId, candidateId) en Application
      Esto blindará aún más la calidad de los datos.
  • Revisa los índices redundantes, como el doble índice en Candidate.email.
    Prisma lo genera así, pero a nivel de base de datos podrías simplificar si no necesitas ambos.

  • Considera usar enums o tablas catálogo para campos como status, employmentType o result.
    Esto evitará valores inconsistentes y facilitará su uso en reporting.


✨ Mensaje final

Muy buen trabajo, se nota que entendiste tanto la parte de modelado como la integración con Prisma.
Los detalles que faltan son ajustes finos propios de alguien que ya está en nivel intermedio–avanzado.

Con un par de CHECK y unicidades adicionales, este esquema estaría perfectamente listo para producción.
¡Sigue así, que vas por muy buen camino! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants