Skip to content

Commit 25e775c

Browse files
committed
cm
1 parent 1c1ee18 commit 25e775c

File tree

2 files changed

+89
-83
lines changed

2 files changed

+89
-83
lines changed

erdiagram.py

Lines changed: 89 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,101 @@
11
from graphviz import Digraph
2+
import os
3+
4+
# Create docs folder if not exists
5+
os.makedirs("docs", exist_ok=True)
26

3-
# Criar diagrama ER
47
dot = Digraph("ERD_PortalEmprego", format="png")
5-
dot.attr(rankdir="LR", size="8")
8+
dot.attr(rankdir="TB", fontsize="12", fontname="Arial")
9+
10+
# Helper: add table-style nodes with optional FK cardinalities
11+
def add_table(name, title, fields, color="lightgray"):
12+
label = f'''<
13+
<TABLE BORDER="1" CELLBORDER="1" CELLSPACING="0">
14+
<TR><TD BGCOLOR="{color}" COLSPAN="2"><B>{title}</B></TD></TR>'''
15+
for f in fields:
16+
label += f'\n <TR><TD ALIGN="LEFT">{f}</TD></TR>'
17+
label += "\n </TABLE>>"
18+
dot.node(name, label=label, shape="none")
619

7-
# Definir estilo
8-
node_attr = {"shape": "record", "fontname": "Arial", "fontsize": "10"}
20+
# Tables with FK cardinalities
21+
add_table("user_profiles", "user_profiles", [
22+
"id (PK)",
23+
"email (UNIQUE)",
24+
"nome_completo",
25+
"perfil",
26+
"telefone",
27+
"criado_em",
28+
"atualizado_em"
29+
], color="lightblue")
930

10-
# Tabelas principais
11-
dot.node("user_profiles", """{
12-
user_profiles |
13-
+ id (PK) \\l
14-
+ email (UNIQUE) \\l
15-
+ nome_completo \\l
16-
+ perfil \\l
17-
+ telefone \\l
18-
+ criado_em \\l
19-
+ atualizado_em \\l
20-
}""", **node_attr)
31+
add_table("candidate_profiles", "candidate_profiles", [
32+
"id (PK)",
33+
"id_utilizador (FK → user_profiles.id) 1:1",
34+
"curriculo_url",
35+
"competencias",
36+
"anos_experiencia",
37+
"formacao",
38+
"salario_min/max",
39+
"localizacoes_preferidas",
40+
"linkedin/github/portfolio"
41+
], color="lightyellow")
2142

22-
dot.node("candidate_profiles", """{
23-
candidate_profiles |
24-
+ id (PK) \\l
25-
+ id_utilizador (FK) \\l
26-
+ curriculo_url \\l
27-
+ competencias \\l
28-
+ anos_experiencia \\l
29-
+ formacao \\l
30-
+ salario_min/max \\l
31-
+ localizacoes_preferidas \\l
32-
+ linkedin/github/portfolio \\l
33-
}""", **node_attr)
43+
add_table("company_profiles", "company_profiles", [
44+
"id (PK)",
45+
"id_utilizador (FK → user_profiles.id) 1:1",
46+
"nome_empresa",
47+
"descricao_empresa",
48+
"sector_atividade",
49+
"dimensao_empresa",
50+
"numero_contribuinte",
51+
"morada/cidade/pais faturacao",
52+
"stripe_customer_id"
53+
], color="lightpink")
3454

35-
dot.node("company_profiles", """{
36-
company_profiles |
37-
+ id (PK) \\l
38-
+ id_utilizador (FK) \\l
39-
+ nome_empresa \\l
40-
+ descricao_empresa \\l
41-
+ sector_atividade \\l
42-
+ dimensao_empresa \\l
43-
+ numero_contribuinte \\l
44-
+ morada/cidade/pais faturacao \\l
45-
+ stripe_customer_id \\l
46-
}""", **node_attr)
55+
add_table("jobs", "jobs", [
56+
"id (PK)",
57+
"id_empresa (FK → company_profiles.id) 1:N",
58+
"titulo",
59+
"descricao",
60+
"salario_min/max",
61+
"localizacao",
62+
"tipo_contrato",
63+
"estado",
64+
"experiencia_requerida",
65+
"categoria"
66+
], color="lightgreen")
4767

48-
dot.node("jobs", """{
49-
jobs |
50-
+ id (PK) \\l
51-
+ id_empresa (FK) \\l
52-
+ titulo \\l
53-
+ descricao \\l
54-
+ salario_min/max \\l
55-
+ localizacao \\l
56-
+ tipo_contrato \\l
57-
+ estado \\l
58-
+ experiencia_requerida \\l
59-
+ categoria \\l
60-
}""", **node_attr)
68+
add_table("job_applications", "job_applications", [
69+
"id (PK)",
70+
"id_oferta (FK → jobs.id) 1:N",
71+
"id_candidato (FK → candidate_profiles.id) 1:N",
72+
"carta_apresentacao_url",
73+
"curriculo_url",
74+
"estado"
75+
], color="orange")
6176

62-
dot.node("job_applications", """{
63-
job_applications |
64-
+ id (PK) \\l
65-
+ id_oferta (FK) \\l
66-
+ id_candidato (FK) \\l
67-
+ carta_apresentacao_url \\l
68-
+ curriculo_url \\l
69-
+ estado \\l
70-
}""", **node_attr)
77+
add_table("payment_history", "payment_history", [
78+
"id (PK)",
79+
"id_empresa (FK → company_profiles.id) 1:N",
80+
"stripe_payment_intent_id",
81+
"valor",
82+
"moeda",
83+
"estado",
84+
"metodo_pagamento",
85+
"iva_percentual",
86+
"valor_com_iva"
87+
], color="lightgray")
7188

72-
dot.node("payment_history", """{
73-
payment_history |
74-
+ id (PK) \\l
75-
+ id_empresa (FK) \\l
76-
+ stripe_payment_intent_id \\l
77-
+ valor \\l
78-
+ moeda \\l
79-
+ estado \\l
80-
+ metodo_pagamento \\l
81-
+ iva_percentual \\l
82-
+ valor_com_iva \\l
83-
}""", **node_attr)
89+
# Simple edge labels for readability (no crow foots)
90+
dot.edge("user_profiles", "candidate_profiles", label="1 → 1")
91+
dot.edge("user_profiles", "company_profiles", label="1 → 1")
92+
dot.edge("company_profiles", "jobs", label="1 → *")
93+
dot.edge("jobs", "job_applications", label="1 → *")
94+
dot.edge("candidate_profiles", "job_applications", label="1 → *")
95+
dot.edge("company_profiles", "payment_history", label="1 → *")
8496

85-
# Relacionamentos
86-
dot.edge("user_profiles", "candidate_profiles", label="1 - n")
87-
dot.edge("user_profiles", "company_profiles", label="1 - n")
88-
dot.edge("company_profiles", "jobs", label="1 - n")
89-
dot.edge("jobs", "job_applications", label="1 - n")
90-
dot.edge("candidate_profiles", "job_applications", label="1 - n")
91-
dot.edge("company_profiles", "payment_history", label="1 - n")
97+
# Export
98+
output_path = "./images/ERD_PortalEmprego"
99+
dot.render(output_path, cleanup=True)
92100

93-
# Exportar
94-
output_path = "/mnt/data/ERD_PortalEmprego.png"
95-
dot.render(output_path, cleanup=True)
101+
print(f"ERD saved to {output_path}.png")

images/ERD_PortalEmprego.png

86.9 KB
Loading

0 commit comments

Comments
 (0)