constec 0.1.0__py3-none-any.whl → 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
constec/db/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ """
2
+ constec.db - Django models for the Constec platform.
3
+
4
+ This package provides centralized model definitions shared between
5
+ constec-core-api and constancia-api.
6
+
7
+ Usage:
8
+ from constec.db.models import Company, User, Session
9
+ """
10
+
11
+ default_app_config = 'constec.db.apps.ConstecDbConfig'
constec/db/apps.py ADDED
@@ -0,0 +1,8 @@
1
+ from django.apps import AppConfig
2
+
3
+
4
+ class ConstecDbConfig(AppConfig):
5
+ default_auto_field = 'django.db.models.BigAutoField'
6
+ name = 'constec.db'
7
+ label = 'constec_db'
8
+ verbose_name = 'Constec Database Models'
@@ -0,0 +1,539 @@
1
+ # Generated by Django 6.0.1 on 2026-01-26 20:41
2
+
3
+ import django.db.models.deletion
4
+ import uuid
5
+ from django.db import migrations, models
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ initial = True
11
+
12
+ dependencies = [
13
+ ]
14
+
15
+ operations = [
16
+ migrations.CreateModel(
17
+ name='ContactType',
18
+ fields=[
19
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
20
+ ('name', models.CharField(max_length=50)),
21
+ ('description', models.TextField(blank=True, null=True)),
22
+ ],
23
+ options={
24
+ 'db_table': 'core"."contact_types',
25
+ },
26
+ ),
27
+ migrations.CreateModel(
28
+ name='Entity',
29
+ fields=[
30
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
31
+ ('external_id', models.CharField(help_text='Entity ID in external ERP system (e.g., cli_Cod, pro_Cod)', max_length=255)),
32
+ ('cuit', models.CharField(blank=True, default='', help_text='CUIT without dashes (for authentication lookup)', max_length=13)),
33
+ ('metadata', models.JSONField(blank=True, default=dict)),
34
+ ],
35
+ options={
36
+ 'db_table': 'erp"."entities',
37
+ },
38
+ ),
39
+ migrations.CreateModel(
40
+ name='FlowTemplate',
41
+ fields=[
42
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
43
+ ('name', models.CharField(max_length=100)),
44
+ ('description', models.TextField()),
45
+ ('category', models.CharField(choices=[('finance', 'Finance & Accounting'), ('customer_service', 'Customer Service'), ('sales', 'Sales & CRM'), ('general', 'General Purpose'), ('custom', 'Custom')], max_length=50)),
46
+ ('graph_definition', models.JSONField(help_text='Graph structure in JSON format with nodes and edges')),
47
+ ('default_config', models.JSONField(default=dict, help_text='Default configuration for this template (LLM, tools, prompts)')),
48
+ ('is_global', models.BooleanField(default=False, help_text='If true, all organizations can use this template')),
49
+ ('is_active', models.BooleanField(default=True)),
50
+ ('version', models.CharField(default='1.0.0', max_length=20)),
51
+ ('created_at', models.DateTimeField(auto_now_add=True)),
52
+ ('updated_at', models.DateTimeField(auto_now=True)),
53
+ ],
54
+ options={
55
+ 'db_table': 'constancia"."flow_templates',
56
+ },
57
+ ),
58
+ migrations.CreateModel(
59
+ name='Module',
60
+ fields=[
61
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
62
+ ('name', models.CharField(max_length=100)),
63
+ ('slug', models.SlugField(max_length=100, null=True)),
64
+ ('description', models.TextField(blank=True, null=True)),
65
+ ('version', models.CharField(max_length=20)),
66
+ ('is_active', models.BooleanField(default=True)),
67
+ ],
68
+ options={
69
+ 'db_table': 'core"."modules',
70
+ },
71
+ ),
72
+ migrations.CreateModel(
73
+ name='Organization',
74
+ fields=[
75
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
76
+ ('name', models.CharField(max_length=255)),
77
+ ('slug', models.SlugField(max_length=100, unique=True)),
78
+ ('description', models.TextField(blank=True, null=True)),
79
+ ],
80
+ options={
81
+ 'db_table': 'core"."organizations',
82
+ },
83
+ ),
84
+ migrations.CreateModel(
85
+ name='Role',
86
+ fields=[
87
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
88
+ ('name', models.CharField(max_length=100)),
89
+ ('description', models.TextField(blank=True, null=True)),
90
+ ],
91
+ options={
92
+ 'db_table': 'erp"."roles',
93
+ },
94
+ ),
95
+ migrations.CreateModel(
96
+ name='System',
97
+ fields=[
98
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
99
+ ('name', models.CharField(max_length=100, unique=True)),
100
+ ('description', models.TextField(blank=True, null=True)),
101
+ ('api_endpoint', models.URLField(blank=True)),
102
+ ('metadata', models.JSONField(blank=True, default=dict)),
103
+ ('created_at', models.DateTimeField(auto_now_add=True, null=True)),
104
+ ('updated_at', models.DateTimeField(auto_now=True, null=True)),
105
+ ],
106
+ options={
107
+ 'db_table': 'erp"."systems',
108
+ },
109
+ ),
110
+ migrations.CreateModel(
111
+ name='Company',
112
+ fields=[
113
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
114
+ ('name', models.CharField(max_length=255)),
115
+ ('legal_name', models.CharField(max_length=255)),
116
+ ('slug', models.SlugField(max_length=100, unique=True)),
117
+ ('website', models.URLField(blank=True, null=True)),
118
+ ('is_active', models.BooleanField(default=True)),
119
+ ('parent_company', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='constec_db.company')),
120
+ ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='companies', to='constec_db.organization')),
121
+ ],
122
+ options={
123
+ 'db_table': 'core"."companies',
124
+ },
125
+ ),
126
+ migrations.CreateModel(
127
+ name='Contact',
128
+ fields=[
129
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
130
+ ('value', models.CharField(max_length=255)),
131
+ ('metadata', models.JSONField(blank=True, default=dict)),
132
+ ('type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contacts', to='constec_db.contacttype')),
133
+ ],
134
+ options={
135
+ 'db_table': 'core"."contacts',
136
+ },
137
+ ),
138
+ migrations.CreateModel(
139
+ name='EntityAuth',
140
+ fields=[
141
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
142
+ ('password_hash', models.CharField(help_text='Bcrypt hashed password', max_length=255)),
143
+ ('is_active', models.BooleanField(default=True, help_text='Whether this account can authenticate')),
144
+ ('created_at', models.DateTimeField(auto_now_add=True)),
145
+ ('updated_at', models.DateTimeField(auto_now=True)),
146
+ ('last_login', models.DateTimeField(blank=True, help_text='Last successful login timestamp', null=True)),
147
+ ('entity', models.OneToOneField(help_text='The ERP entity these credentials belong to', on_delete=django.db.models.deletion.CASCADE, related_name='auth', to='constec_db.entity')),
148
+ ],
149
+ options={
150
+ 'verbose_name': 'Entity Authentication',
151
+ 'verbose_name_plural': 'Entity Authentications',
152
+ 'db_table': 'erp"."entity_auth',
153
+ },
154
+ ),
155
+ migrations.CreateModel(
156
+ name='Flow',
157
+ fields=[
158
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
159
+ ('name', models.CharField(max_length=100)),
160
+ ('description', models.TextField(blank=True, null=True)),
161
+ ('graph_definition', models.JSONField(blank=True, help_text='Custom graph structure (only if not using template)', null=True)),
162
+ ('config', models.JSONField(default=dict, help_text='Configuration that merges with template.default_config')),
163
+ ('is_active', models.BooleanField(default=True)),
164
+ ('is_default', models.BooleanField(default=False, help_text='Whether this is the default flow for the company')),
165
+ ('created_at', models.DateTimeField(auto_now_add=True)),
166
+ ('updated_at', models.DateTimeField(auto_now=True)),
167
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='flows', to='constec_db.company')),
168
+ ('template', models.ForeignKey(blank=True, help_text="If set, uses template's graph. config overrides template defaults.", null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='flows', to='constec_db.flowtemplate')),
169
+ ],
170
+ options={
171
+ 'db_table': 'constancia"."flows',
172
+ },
173
+ ),
174
+ migrations.CreateModel(
175
+ name='CompanyModule',
176
+ fields=[
177
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
178
+ ('is_enabled', models.BooleanField(default=True)),
179
+ ('settings', models.JSONField(blank=True, default=dict)),
180
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='company_modules', to='constec_db.company')),
181
+ ('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='company_modules', to='constec_db.module')),
182
+ ],
183
+ options={
184
+ 'db_table': 'core"."company_modules',
185
+ },
186
+ ),
187
+ migrations.AddField(
188
+ model_name='flowtemplate',
189
+ name='organization',
190
+ field=models.ForeignKey(blank=True, help_text='Organization that owns this template (null for global)', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='flow_templates', to='constec_db.organization'),
191
+ ),
192
+ migrations.CreateModel(
193
+ name='OrganizationRole',
194
+ fields=[
195
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
196
+ ('name', models.CharField(max_length=100)),
197
+ ('description', models.TextField(blank=True, null=True)),
198
+ ('permissions', models.JSONField(default=dict)),
199
+ ('is_system_role', models.BooleanField(default=False)),
200
+ ('organization', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='organization_roles', to='constec_db.organization')),
201
+ ],
202
+ options={
203
+ 'db_table': 'core"."organization_roles',
204
+ },
205
+ ),
206
+ migrations.CreateModel(
207
+ name='OrganizationUser',
208
+ fields=[
209
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
210
+ ('name', models.CharField(max_length=255)),
211
+ ('email', models.EmailField(max_length=254, unique=True)),
212
+ ('password_hash', models.CharField(max_length=255)),
213
+ ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='users', to='constec_db.organization')),
214
+ ('role', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='constec_db.organizationrole')),
215
+ ],
216
+ options={
217
+ 'db_table': 'core"."organization_users',
218
+ },
219
+ ),
220
+ migrations.AddField(
221
+ model_name='flowtemplate',
222
+ name='created_by',
223
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_templates', to='constec_db.organizationuser'),
224
+ ),
225
+ migrations.CreateModel(
226
+ name='Person',
227
+ fields=[
228
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
229
+ ('first_name', models.CharField(max_length=100)),
230
+ ('last_name', models.CharField(max_length=100)),
231
+ ('full_name', models.CharField(max_length=255)),
232
+ ('metadata', models.JSONField(blank=True, default=dict)),
233
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='persons', to='constec_db.company')),
234
+ ],
235
+ options={
236
+ 'db_table': 'core"."persons',
237
+ },
238
+ ),
239
+ migrations.AddField(
240
+ model_name='entity',
241
+ name='person',
242
+ field=models.ForeignKey(blank=True, help_text='Optional link to Core person', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='erp_entities', to='constec_db.person'),
243
+ ),
244
+ migrations.CreateModel(
245
+ name='PersonContact',
246
+ fields=[
247
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
248
+ ('is_primary', models.BooleanField(default=False)),
249
+ ('contact', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_contacts', to='constec_db.contact')),
250
+ ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_contacts', to='constec_db.person')),
251
+ ],
252
+ options={
253
+ 'db_table': 'core"."person_contacts',
254
+ },
255
+ ),
256
+ migrations.CreateModel(
257
+ name='PersonTag',
258
+ fields=[
259
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
260
+ ('name', models.CharField(max_length=50)),
261
+ ('color', models.CharField(blank=True, max_length=7, null=True)),
262
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_tags', to='constec_db.company')),
263
+ ],
264
+ options={
265
+ 'db_table': 'core"."person_tags',
266
+ },
267
+ ),
268
+ migrations.CreateModel(
269
+ name='PersonTagged',
270
+ fields=[
271
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
272
+ ('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_items', to='constec_db.person')),
273
+ ('tag', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tagged_persons', to='constec_db.persontag')),
274
+ ],
275
+ options={
276
+ 'db_table': 'core"."person_tagged',
277
+ },
278
+ ),
279
+ migrations.AddField(
280
+ model_name='entity',
281
+ name='role',
282
+ field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='entities', to='constec_db.role'),
283
+ ),
284
+ migrations.CreateModel(
285
+ name='Session',
286
+ fields=[
287
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
288
+ ('metadata', models.JSONField(default=dict, help_text='Session context (connection, role, etc.)')),
289
+ ('is_active', models.BooleanField(default=True)),
290
+ ('ended_at', models.DateTimeField(blank=True, null=True)),
291
+ ('created_at', models.DateTimeField(auto_now_add=True)),
292
+ ('updated_at', models.DateTimeField(auto_now=True)),
293
+ ('company', models.ForeignKey(help_text='The company this session belongs to', on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='constec_db.company')),
294
+ ('flow', models.ForeignKey(help_text='AI flow configuration to use', on_delete=django.db.models.deletion.PROTECT, related_name='sessions', to='constec_db.flow')),
295
+ ('user', models.ForeignKey(help_text='The person chatting (can be employee or client)', on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='constec_db.person')),
296
+ ],
297
+ options={
298
+ 'db_table': 'constancia"."sessions',
299
+ },
300
+ ),
301
+ migrations.CreateModel(
302
+ name='Message',
303
+ fields=[
304
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
305
+ ('role', models.CharField(choices=[('user', 'User'), ('assistant', 'Assistant')], max_length=20)),
306
+ ('content', models.TextField()),
307
+ ('metadata', models.JSONField(blank=True, default=dict, help_text='Additional message data: tool calls, errors, context, etc.')),
308
+ ('created_at', models.DateTimeField(auto_now_add=True)),
309
+ ('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='constec_db.session')),
310
+ ],
311
+ options={
312
+ 'db_table': 'constancia"."messages',
313
+ 'ordering': ['created_at'],
314
+ },
315
+ ),
316
+ migrations.AddField(
317
+ model_name='role',
318
+ name='system',
319
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='roles', to='constec_db.system'),
320
+ ),
321
+ migrations.AddField(
322
+ model_name='entity',
323
+ name='system',
324
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='entities', to='constec_db.system'),
325
+ ),
326
+ migrations.CreateModel(
327
+ name='Connection',
328
+ fields=[
329
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
330
+ ('name', models.CharField(blank=True, default='', help_text='Descriptive name for this connection', max_length=100)),
331
+ ('slug', models.CharField(max_length=50)),
332
+ ('db_type', models.CharField(choices=[('mssql', 'SQL Server'), ('postgresql', 'PostgreSQL'), ('mysql', 'MySQL')], default='mssql', max_length=20)),
333
+ ('host', models.CharField(max_length=255)),
334
+ ('port', models.IntegerField()),
335
+ ('database', models.CharField(max_length=100)),
336
+ ('username', models.CharField(max_length=100)),
337
+ ('encrypted_password', models.TextField()),
338
+ ('is_active', models.BooleanField(default=True)),
339
+ ('last_tested_at', models.DateTimeField(blank=True, null=True)),
340
+ ('created_at', models.DateTimeField(auto_now_add=True)),
341
+ ('updated_at', models.DateTimeField(auto_now=True)),
342
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='erp_connections', to='constec_db.company')),
343
+ ('system', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='connections', to='constec_db.system')),
344
+ ],
345
+ options={
346
+ 'db_table': 'erp"."connections',
347
+ },
348
+ ),
349
+ migrations.CreateModel(
350
+ name='CompanySystem',
351
+ fields=[
352
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
353
+ ('is_primary', models.BooleanField(default=False, help_text='Whether this is the primary ERP system for the company')),
354
+ ('is_active', models.BooleanField(default=True)),
355
+ ('metadata', models.JSONField(blank=True, default=dict)),
356
+ ('created_at', models.DateTimeField(auto_now_add=True)),
357
+ ('updated_at', models.DateTimeField(auto_now=True)),
358
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='erp_systems', to='constec_db.company')),
359
+ ('system', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='company_assignments', to='constec_db.system')),
360
+ ],
361
+ options={
362
+ 'db_table': 'erp"."company_systems',
363
+ },
364
+ ),
365
+ migrations.CreateModel(
366
+ name='TagCategory',
367
+ fields=[
368
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
369
+ ('name', models.CharField(max_length=50)),
370
+ ('description', models.TextField(blank=True, null=True)),
371
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tag_categories', to='constec_db.company')),
372
+ ],
373
+ options={
374
+ 'db_table': 'core"."tag_categories',
375
+ },
376
+ ),
377
+ migrations.AddField(
378
+ model_name='persontag',
379
+ name='category',
380
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='person_tags', to='constec_db.tagcategory'),
381
+ ),
382
+ migrations.CreateModel(
383
+ name='User',
384
+ fields=[
385
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
386
+ ('name', models.CharField(max_length=255)),
387
+ ('email', models.EmailField(max_length=254, unique=True)),
388
+ ('password_hash', models.CharField(max_length=255)),
389
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='users', to='constec_db.company')),
390
+ ],
391
+ options={
392
+ 'db_table': 'core"."users',
393
+ },
394
+ ),
395
+ migrations.CreateModel(
396
+ name='UserGroup',
397
+ fields=[
398
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
399
+ ('name', models.CharField(max_length=100)),
400
+ ('description', models.TextField(blank=True, null=True)),
401
+ ('company', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='user_groups', to='constec_db.company')),
402
+ ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sub_groups', to='constec_db.usergroup')),
403
+ ('users', models.ManyToManyField(related_name='groups', to='constec_db.user')),
404
+ ],
405
+ options={
406
+ 'db_table': 'core"."user_groups',
407
+ },
408
+ ),
409
+ migrations.CreateModel(
410
+ name='UserRole',
411
+ fields=[
412
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
413
+ ('name', models.CharField(max_length=100)),
414
+ ('description', models.TextField(blank=True, null=True)),
415
+ ('permissions', models.JSONField(default=dict)),
416
+ ('is_system_role', models.BooleanField(default=False)),
417
+ ('company', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='user_roles', to='constec_db.company')),
418
+ ],
419
+ options={
420
+ 'db_table': 'core"."user_roles',
421
+ },
422
+ ),
423
+ migrations.CreateModel(
424
+ name='UserCompanyAccess',
425
+ fields=[
426
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
427
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_accesses', to='constec_db.company')),
428
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='company_accesses', to='constec_db.user')),
429
+ ('role', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='user_accesses', to='constec_db.userrole')),
430
+ ],
431
+ options={
432
+ 'db_table': 'core"."user_company_access',
433
+ },
434
+ ),
435
+ migrations.AddIndex(
436
+ model_name='flow',
437
+ index=models.Index(fields=['company', 'is_default'], name='flows_company_982968_idx'),
438
+ ),
439
+ migrations.AddIndex(
440
+ model_name='flow',
441
+ index=models.Index(fields=['template', 'is_active'], name='flows_templat_638f1d_idx'),
442
+ ),
443
+ migrations.AlterUniqueTogether(
444
+ name='flow',
445
+ unique_together={('company', 'name')},
446
+ ),
447
+ migrations.AlterUniqueTogether(
448
+ name='companymodule',
449
+ unique_together={('company', 'module')},
450
+ ),
451
+ migrations.AlterUniqueTogether(
452
+ name='organizationrole',
453
+ unique_together={('organization', 'name')},
454
+ ),
455
+ migrations.AddIndex(
456
+ model_name='flowtemplate',
457
+ index=models.Index(fields=['organization', 'is_global'], name='flow_templa_organiz_abebc3_idx'),
458
+ ),
459
+ migrations.AddIndex(
460
+ model_name='flowtemplate',
461
+ index=models.Index(fields=['category', 'is_active'], name='flow_templa_categor_976487_idx'),
462
+ ),
463
+ migrations.AlterUniqueTogether(
464
+ name='flowtemplate',
465
+ unique_together={('organization', 'name', 'version')},
466
+ ),
467
+ migrations.AlterUniqueTogether(
468
+ name='personcontact',
469
+ unique_together={('person', 'contact')},
470
+ ),
471
+ migrations.AlterUniqueTogether(
472
+ name='persontagged',
473
+ unique_together={('person', 'tag')},
474
+ ),
475
+ migrations.AddIndex(
476
+ model_name='session',
477
+ index=models.Index(fields=['company', 'is_active'], name='sessions_company_30036a_idx'),
478
+ ),
479
+ migrations.AddIndex(
480
+ model_name='session',
481
+ index=models.Index(fields=['user', 'is_active'], name='sessions_user_id_85103c_idx'),
482
+ ),
483
+ migrations.AddIndex(
484
+ model_name='session',
485
+ index=models.Index(fields=['-created_at'], name='sessions_created_eb29b2_idx'),
486
+ ),
487
+ migrations.AddIndex(
488
+ model_name='message',
489
+ index=models.Index(fields=['session', 'created_at'], name='messages_session_1b3070_idx'),
490
+ ),
491
+ migrations.AlterUniqueTogether(
492
+ name='role',
493
+ unique_together={('system', 'name')},
494
+ ),
495
+ migrations.AddIndex(
496
+ model_name='entity',
497
+ index=models.Index(fields=['cuit'], name='entities_cuit_ad5bc3_idx'),
498
+ ),
499
+ migrations.AddIndex(
500
+ model_name='entity',
501
+ index=models.Index(fields=['system', 'cuit'], name='entities_system__347218_idx'),
502
+ ),
503
+ migrations.AlterUniqueTogether(
504
+ name='entity',
505
+ unique_together={('system', 'role', 'external_id')},
506
+ ),
507
+ migrations.AlterUniqueTogether(
508
+ name='connection',
509
+ unique_together={('system', 'slug')},
510
+ ),
511
+ migrations.AddIndex(
512
+ model_name='companysystem',
513
+ index=models.Index(fields=['company', 'is_primary'], name='company_sys_company_e5ff34_idx'),
514
+ ),
515
+ migrations.AddIndex(
516
+ model_name='companysystem',
517
+ index=models.Index(fields=['system', 'is_active'], name='company_sys_system__aeef9f_idx'),
518
+ ),
519
+ migrations.AlterUniqueTogether(
520
+ name='companysystem',
521
+ unique_together={('company', 'system')},
522
+ ),
523
+ migrations.AlterUniqueTogether(
524
+ name='persontag',
525
+ unique_together={('company', 'category', 'name')},
526
+ ),
527
+ migrations.AlterUniqueTogether(
528
+ name='usergroup',
529
+ unique_together={('company', 'name')},
530
+ ),
531
+ migrations.AlterUniqueTogether(
532
+ name='userrole',
533
+ unique_together={('company', 'name')},
534
+ ),
535
+ migrations.AlterUniqueTogether(
536
+ name='usercompanyaccess',
537
+ unique_together={('user', 'company')},
538
+ ),
539
+ ]
File without changes
@@ -0,0 +1,91 @@
1
+ """
2
+ constec.db.models - All Django models for the Constec platform.
3
+
4
+ Usage:
5
+ from constec.db.models import Company, User, Session, Message
6
+
7
+ # ERP models (from erp schema, no prefix needed):
8
+ from constec.db.models import System, Connection, Entity
9
+
10
+ # Or import from specific modules:
11
+ from constec.db.models.organization import Organization
12
+ from constec.db.models.erp import System, Connection
13
+ from constec.db.models.erp_entity import Role, Entity, EntityAuth
14
+ """
15
+
16
+ # Base
17
+ from .base import UUIDModel
18
+
19
+ # Core models (core schema)
20
+ from .organization import Organization, OrganizationRole, OrganizationUser
21
+ from .company import Company
22
+ from .user import User, UserRole, UserCompanyAccess
23
+ from .person import Person
24
+ from .group import UserGroup
25
+ from .contact import ContactType, Contact, PersonContact
26
+ from .tag import TagCategory, PersonTag, PersonTagged
27
+ from .module import Module, CompanyModule
28
+
29
+ # ERP models (erp schema)
30
+ from .erp import System, CompanySystem, Connection
31
+ from .erp_entity import Role, Entity, EntityAuth
32
+
33
+ # Aliases for backward compatibility
34
+ ErpSystem = System
35
+ CompanyErpSystem = CompanySystem
36
+ ErpConnection = Connection
37
+ ErpRole = Role
38
+ ErpEntity = Entity
39
+
40
+ # Constancia models (constancia schema)
41
+ from .flow import FlowTemplate, Flow
42
+ from .session import Session, Message
43
+
44
+
45
+ __all__ = [
46
+ # Base
47
+ 'UUIDModel',
48
+ # Organization
49
+ 'Organization',
50
+ 'OrganizationRole',
51
+ 'OrganizationUser',
52
+ # Company
53
+ 'Company',
54
+ # User
55
+ 'User',
56
+ 'UserRole',
57
+ 'UserCompanyAccess',
58
+ # Person
59
+ 'Person',
60
+ # Group
61
+ 'UserGroup',
62
+ # Contact
63
+ 'ContactType',
64
+ 'Contact',
65
+ 'PersonContact',
66
+ # Tag
67
+ 'TagCategory',
68
+ 'PersonTag',
69
+ 'PersonTagged',
70
+ # Module
71
+ 'Module',
72
+ 'CompanyModule',
73
+ # ERP (erp schema)
74
+ 'System',
75
+ 'CompanySystem',
76
+ 'Connection',
77
+ 'Role',
78
+ 'Entity',
79
+ 'EntityAuth',
80
+ # ERP aliases (backward compatibility)
81
+ 'ErpSystem',
82
+ 'CompanyErpSystem',
83
+ 'ErpConnection',
84
+ 'ErpRole',
85
+ 'ErpEntity',
86
+ # Constancia (constancia schema)
87
+ 'FlowTemplate',
88
+ 'Flow',
89
+ 'Session',
90
+ 'Message',
91
+ ]
@@ -0,0 +1,14 @@
1
+ import uuid
2
+ from django.db import models
3
+
4
+
5
+ class UUIDModel(models.Model):
6
+ """Base model with UUID as primary key.
7
+
8
+ All Constec models inherit from this to ensure consistent
9
+ UUID-based primary keys across the platform.
10
+ """
11
+ id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
12
+
13
+ class Meta:
14
+ abstract = True