constec 0.3.4__py3-none-any.whl → 0.4.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.
@@ -0,0 +1,345 @@
1
+ # Generated by Django 6.0.1 on 2026-01-29 13:27
2
+
3
+ import django.utils.timezone
4
+ from django.db import migrations, models
5
+
6
+
7
+ class Migration(migrations.Migration):
8
+
9
+ dependencies = [
10
+ ('constec_db', '0003_remove_module_level'),
11
+ ]
12
+
13
+ operations = [
14
+ migrations.AddField(
15
+ model_name='company',
16
+ name='created_at',
17
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
18
+ preserve_default=False,
19
+ ),
20
+ migrations.AddField(
21
+ model_name='company',
22
+ name='updated_at',
23
+ field=models.DateTimeField(auto_now=True),
24
+ ),
25
+ migrations.AddField(
26
+ model_name='companymodule',
27
+ name='created_at',
28
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
29
+ preserve_default=False,
30
+ ),
31
+ migrations.AddField(
32
+ model_name='companymodule',
33
+ name='is_active',
34
+ field=models.BooleanField(default=True),
35
+ ),
36
+ migrations.AddField(
37
+ model_name='companymodule',
38
+ name='updated_at',
39
+ field=models.DateTimeField(auto_now=True),
40
+ ),
41
+ migrations.AddField(
42
+ model_name='contact',
43
+ name='created_at',
44
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
45
+ preserve_default=False,
46
+ ),
47
+ migrations.AddField(
48
+ model_name='contact',
49
+ name='is_active',
50
+ field=models.BooleanField(default=True),
51
+ ),
52
+ migrations.AddField(
53
+ model_name='contact',
54
+ name='updated_at',
55
+ field=models.DateTimeField(auto_now=True),
56
+ ),
57
+ migrations.AddField(
58
+ model_name='contacttype',
59
+ name='created_at',
60
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
61
+ preserve_default=False,
62
+ ),
63
+ migrations.AddField(
64
+ model_name='contacttype',
65
+ name='is_active',
66
+ field=models.BooleanField(default=True),
67
+ ),
68
+ migrations.AddField(
69
+ model_name='contacttype',
70
+ name='updated_at',
71
+ field=models.DateTimeField(auto_now=True),
72
+ ),
73
+ migrations.AddField(
74
+ model_name='entity',
75
+ name='created_at',
76
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
77
+ preserve_default=False,
78
+ ),
79
+ migrations.AddField(
80
+ model_name='entity',
81
+ name='is_active',
82
+ field=models.BooleanField(default=True),
83
+ ),
84
+ migrations.AddField(
85
+ model_name='entity',
86
+ name='updated_at',
87
+ field=models.DateTimeField(auto_now=True),
88
+ ),
89
+ migrations.AddField(
90
+ model_name='message',
91
+ name='is_active',
92
+ field=models.BooleanField(default=True),
93
+ ),
94
+ migrations.AddField(
95
+ model_name='message',
96
+ name='updated_at',
97
+ field=models.DateTimeField(auto_now=True),
98
+ ),
99
+ migrations.AddField(
100
+ model_name='module',
101
+ name='created_at',
102
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
103
+ preserve_default=False,
104
+ ),
105
+ migrations.AddField(
106
+ model_name='module',
107
+ name='updated_at',
108
+ field=models.DateTimeField(auto_now=True),
109
+ ),
110
+ migrations.AddField(
111
+ model_name='organization',
112
+ name='created_at',
113
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
114
+ preserve_default=False,
115
+ ),
116
+ migrations.AddField(
117
+ model_name='organization',
118
+ name='is_active',
119
+ field=models.BooleanField(default=True),
120
+ ),
121
+ migrations.AddField(
122
+ model_name='organization',
123
+ name='updated_at',
124
+ field=models.DateTimeField(auto_now=True),
125
+ ),
126
+ migrations.AddField(
127
+ model_name='organizationmodule',
128
+ name='is_active',
129
+ field=models.BooleanField(default=True),
130
+ ),
131
+ migrations.AddField(
132
+ model_name='organizationrole',
133
+ name='created_at',
134
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
135
+ preserve_default=False,
136
+ ),
137
+ migrations.AddField(
138
+ model_name='organizationrole',
139
+ name='is_active',
140
+ field=models.BooleanField(default=True),
141
+ ),
142
+ migrations.AddField(
143
+ model_name='organizationrole',
144
+ name='updated_at',
145
+ field=models.DateTimeField(auto_now=True),
146
+ ),
147
+ migrations.AddField(
148
+ model_name='organizationuser',
149
+ name='created_at',
150
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
151
+ preserve_default=False,
152
+ ),
153
+ migrations.AddField(
154
+ model_name='organizationuser',
155
+ name='is_active',
156
+ field=models.BooleanField(default=True),
157
+ ),
158
+ migrations.AddField(
159
+ model_name='organizationuser',
160
+ name='updated_at',
161
+ field=models.DateTimeField(auto_now=True),
162
+ ),
163
+ migrations.AddField(
164
+ model_name='person',
165
+ name='created_at',
166
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
167
+ preserve_default=False,
168
+ ),
169
+ migrations.AddField(
170
+ model_name='person',
171
+ name='is_active',
172
+ field=models.BooleanField(default=True),
173
+ ),
174
+ migrations.AddField(
175
+ model_name='person',
176
+ name='updated_at',
177
+ field=models.DateTimeField(auto_now=True),
178
+ ),
179
+ migrations.AddField(
180
+ model_name='personcontact',
181
+ name='created_at',
182
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
183
+ preserve_default=False,
184
+ ),
185
+ migrations.AddField(
186
+ model_name='personcontact',
187
+ name='is_active',
188
+ field=models.BooleanField(default=True),
189
+ ),
190
+ migrations.AddField(
191
+ model_name='personcontact',
192
+ name='updated_at',
193
+ field=models.DateTimeField(auto_now=True),
194
+ ),
195
+ migrations.AddField(
196
+ model_name='persontag',
197
+ name='created_at',
198
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
199
+ preserve_default=False,
200
+ ),
201
+ migrations.AddField(
202
+ model_name='persontag',
203
+ name='is_active',
204
+ field=models.BooleanField(default=True),
205
+ ),
206
+ migrations.AddField(
207
+ model_name='persontag',
208
+ name='updated_at',
209
+ field=models.DateTimeField(auto_now=True),
210
+ ),
211
+ migrations.AddField(
212
+ model_name='persontagged',
213
+ name='created_at',
214
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
215
+ preserve_default=False,
216
+ ),
217
+ migrations.AddField(
218
+ model_name='persontagged',
219
+ name='is_active',
220
+ field=models.BooleanField(default=True),
221
+ ),
222
+ migrations.AddField(
223
+ model_name='persontagged',
224
+ name='updated_at',
225
+ field=models.DateTimeField(auto_now=True),
226
+ ),
227
+ migrations.AddField(
228
+ model_name='role',
229
+ name='created_at',
230
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
231
+ preserve_default=False,
232
+ ),
233
+ migrations.AddField(
234
+ model_name='role',
235
+ name='is_active',
236
+ field=models.BooleanField(default=True),
237
+ ),
238
+ migrations.AddField(
239
+ model_name='role',
240
+ name='updated_at',
241
+ field=models.DateTimeField(auto_now=True),
242
+ ),
243
+ migrations.AddField(
244
+ model_name='system',
245
+ name='is_active',
246
+ field=models.BooleanField(default=True),
247
+ ),
248
+ migrations.AddField(
249
+ model_name='tagcategory',
250
+ name='created_at',
251
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
252
+ preserve_default=False,
253
+ ),
254
+ migrations.AddField(
255
+ model_name='tagcategory',
256
+ name='is_active',
257
+ field=models.BooleanField(default=True),
258
+ ),
259
+ migrations.AddField(
260
+ model_name='tagcategory',
261
+ name='updated_at',
262
+ field=models.DateTimeField(auto_now=True),
263
+ ),
264
+ migrations.AddField(
265
+ model_name='user',
266
+ name='created_at',
267
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
268
+ preserve_default=False,
269
+ ),
270
+ migrations.AddField(
271
+ model_name='user',
272
+ name='is_active',
273
+ field=models.BooleanField(default=True),
274
+ ),
275
+ migrations.AddField(
276
+ model_name='user',
277
+ name='updated_at',
278
+ field=models.DateTimeField(auto_now=True),
279
+ ),
280
+ migrations.AddField(
281
+ model_name='usercompanyaccess',
282
+ name='created_at',
283
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
284
+ preserve_default=False,
285
+ ),
286
+ migrations.AddField(
287
+ model_name='usercompanyaccess',
288
+ name='is_active',
289
+ field=models.BooleanField(default=True),
290
+ ),
291
+ migrations.AddField(
292
+ model_name='usercompanyaccess',
293
+ name='updated_at',
294
+ field=models.DateTimeField(auto_now=True),
295
+ ),
296
+ migrations.AddField(
297
+ model_name='usergroup',
298
+ name='created_at',
299
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
300
+ preserve_default=False,
301
+ ),
302
+ migrations.AddField(
303
+ model_name='usergroup',
304
+ name='is_active',
305
+ field=models.BooleanField(default=True),
306
+ ),
307
+ migrations.AddField(
308
+ model_name='usergroup',
309
+ name='updated_at',
310
+ field=models.DateTimeField(auto_now=True),
311
+ ),
312
+ migrations.AddField(
313
+ model_name='userrole',
314
+ name='created_at',
315
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
316
+ preserve_default=False,
317
+ ),
318
+ migrations.AddField(
319
+ model_name='userrole',
320
+ name='is_active',
321
+ field=models.BooleanField(default=True),
322
+ ),
323
+ migrations.AddField(
324
+ model_name='userrole',
325
+ name='updated_at',
326
+ field=models.DateTimeField(auto_now=True),
327
+ ),
328
+ migrations.AlterField(
329
+ model_name='entityauth',
330
+ name='is_active',
331
+ field=models.BooleanField(default=True),
332
+ ),
333
+ migrations.AlterField(
334
+ model_name='system',
335
+ name='created_at',
336
+ field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
337
+ preserve_default=False,
338
+ ),
339
+ migrations.AlterField(
340
+ model_name='system',
341
+ name='updated_at',
342
+ field=models.DateTimeField(auto_now=True, default=django.utils.timezone.now),
343
+ preserve_default=False,
344
+ ),
345
+ ]
@@ -0,0 +1,46 @@
1
+ # Generated manually on 2026-02-02 for automations schema
2
+
3
+ import uuid
4
+ from django.conf import settings
5
+ from django.db import migrations, models
6
+ import django.db.models.deletion
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+
11
+ dependencies = [
12
+ ('constec_db', '0004_rename_entities_company_cuit_idx_entities_company_e2c50f_idx_and_more'),
13
+ ]
14
+
15
+ operations = [
16
+ migrations.CreateModel(
17
+ name='Event',
18
+ fields=[
19
+ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
20
+ ('created_at', models.DateTimeField(auto_now_add=True)),
21
+ ('updated_at', models.DateTimeField(auto_now=True)),
22
+ ('event_type', models.CharField(choices=[('notification', 'Notification'), ('automation', 'Automation')], max_length=50)),
23
+ ('title', models.CharField(max_length=255)),
24
+ ('description', models.TextField(blank=True)),
25
+ ('status', models.CharField(choices=[('active', 'Active'), ('paused', 'Paused'), ('completed', 'Completed'), ('failed', 'Failed'), ('cancelled', 'Cancelled')], default='active', max_length=20)),
26
+ ('recurrence_type', models.CharField(choices=[('punctual', 'Punctual'), ('periodic', 'Periodic')], help_text='Tipo de recurrencia: puntual (fechas específicas) o periódico', max_length=20)),
27
+ ('recurrence_config', models.JSONField(help_text='Configuración de recurrencia en formato JSON')),
28
+ ('config', models.JSONField(default=dict, help_text='Configuración específica según event_type (mensaje, URL, etc.)')),
29
+ ('next_execution_at', models.DateTimeField(blank=True, db_index=True, help_text='Próxima fecha/hora de ejecución calculada', null=True)),
30
+ ('last_executed_at', models.DateTimeField(blank=True, help_text='Última vez que se ejecutó', null=True)),
31
+ ('execution_count', models.IntegerField(default=0, help_text='Cantidad de veces que se ha ejecutado')),
32
+ ('company', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='constec_db.company')),
33
+ ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='created_events', to=settings.AUTH_USER_MODEL)),
34
+ ],
35
+ options={
36
+ 'db_table': '"automations"."events"',
37
+ 'ordering': ['next_execution_at'],
38
+ 'indexes': [
39
+ models.Index(fields=['company', 'event_type'], name='automations_company_ebe85a_idx'),
40
+ models.Index(fields=['status', 'next_execution_at'], name='automations_status_a3d45f_idx'),
41
+ models.Index(fields=['recurrence_type'], name='automations_recurre_5d8b2c_idx'),
42
+ ],
43
+ },
44
+ bases=(models.Model,),
45
+ ),
46
+ ]
@@ -41,6 +41,9 @@ ErpEntity = Entity
41
41
  from .flow import FlowTemplate, Flow
42
42
  from .session import Session, Message
43
43
 
44
+ # Automations models (automations schema)
45
+ from .automation import Event
46
+
44
47
 
45
48
  __all__ = [
46
49
  # Base
@@ -89,4 +92,6 @@ __all__ = [
89
92
  'Flow',
90
93
  'Session',
91
94
  'Message',
95
+ # Automations (automations schema)
96
+ 'Event',
92
97
  ]
@@ -0,0 +1,99 @@
1
+ """Automation models for event scheduling and task automation."""
2
+
3
+ import uuid
4
+ from django.db import models
5
+ from .base import UUIDModel
6
+ from .company import Company
7
+ from .user import User
8
+
9
+
10
+ class Event(UUIDModel):
11
+ """
12
+ Evento programado con soporte para múltiples tipos y recurrencia flexible.
13
+
14
+ Tipos soportados:
15
+ - notification: Notificaciones programadas
16
+ - automation: Automatizaciones programadas (acciones HTTP, workflows, etc.)
17
+ """
18
+
19
+ EVENT_TYPE_CHOICES = [
20
+ ('notification', 'Notification'),
21
+ ('automation', 'Automation'),
22
+ ]
23
+
24
+ STATUS_CHOICES = [
25
+ ('active', 'Active'), # Activo y programado
26
+ ('paused', 'Paused'), # Pausado temporalmente
27
+ ('completed', 'Completed'), # Completado (para puntuales)
28
+ ('failed', 'Failed'), # Falló la última ejecución
29
+ ('cancelled', 'Cancelled'), # Cancelado permanentemente
30
+ ]
31
+
32
+ RECURRENCE_TYPE_CHOICES = [
33
+ ('punctual', 'Punctual'), # Una o más veces en fechas específicas
34
+ ('periodic', 'Periodic'), # Recurrente
35
+ ]
36
+
37
+ # FKs
38
+ company = models.ForeignKey(Company, on_delete=models.CASCADE, db_index=True)
39
+
40
+ # Tipo de evento
41
+ event_type = models.CharField(max_length=50, choices=EVENT_TYPE_CHOICES)
42
+
43
+ # Info básica
44
+ title = models.CharField(max_length=255)
45
+ description = models.TextField(blank=True)
46
+ status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active')
47
+
48
+ # Recurrencia
49
+ recurrence_type = models.CharField(
50
+ max_length=20,
51
+ choices=RECURRENCE_TYPE_CHOICES,
52
+ help_text="Tipo de recurrencia: puntual (fechas específicas) o periódico"
53
+ )
54
+ recurrence_config = models.JSONField(
55
+ help_text="Configuración de recurrencia en formato JSON"
56
+ )
57
+
58
+ # Configuración específica del tipo de evento
59
+ config = models.JSONField(
60
+ default=dict,
61
+ help_text="Configuración específica según event_type (mensaje, URL, etc.)"
62
+ )
63
+
64
+ # Control de ejecución
65
+ next_execution_at = models.DateTimeField(
66
+ null=True,
67
+ blank=True,
68
+ db_index=True,
69
+ help_text="Próxima fecha/hora de ejecución calculada"
70
+ )
71
+ last_executed_at = models.DateTimeField(
72
+ null=True,
73
+ blank=True,
74
+ help_text="Última vez que se ejecutó"
75
+ )
76
+ execution_count = models.IntegerField(
77
+ default=0,
78
+ help_text="Cantidad de veces que se ha ejecutado"
79
+ )
80
+
81
+ # Auditoría
82
+ created_by = models.ForeignKey(
83
+ User,
84
+ on_delete=models.CASCADE,
85
+ related_name='created_events'
86
+ )
87
+
88
+ class Meta:
89
+ db_table = '"automations"."events"'
90
+ app_label = 'constec_db'
91
+ indexes = [
92
+ models.Index(fields=['company', 'event_type']),
93
+ models.Index(fields=['status', 'next_execution_at']),
94
+ models.Index(fields=['recurrence_type']),
95
+ ]
96
+ ordering = ['next_execution_at']
97
+
98
+ def __str__(self):
99
+ return f"{self.event_type}: {self.title}"
constec/db/models/base.py CHANGED
@@ -3,12 +3,21 @@ from django.db import models
3
3
 
4
4
 
5
5
  class UUIDModel(models.Model):
6
- """Base model with UUID as primary key.
6
+ """Base model with UUID primary key and common audit fields.
7
7
 
8
8
  All Constec models inherit from this to ensure consistent
9
- UUID-based primary keys across the platform.
9
+ UUID-based primary keys and audit fields across the platform.
10
+
11
+ Fields provided:
12
+ - id: UUID primary key
13
+ - is_active: soft delete flag
14
+ - created_at: auto-set on creation
15
+ - updated_at: auto-set on every save
10
16
  """
11
17
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
18
+ is_active = models.BooleanField(default=True)
19
+ created_at = models.DateTimeField(auto_now_add=True)
20
+ updated_at = models.DateTimeField(auto_now=True)
12
21
 
13
22
  class Meta:
14
23
  abstract = True
@@ -22,7 +22,6 @@ class Company(UUIDModel):
22
22
  related_name='children'
23
23
  )
24
24
  website = models.URLField(blank=True, null=True)
25
- is_active = models.BooleanField(default=True)
26
25
 
27
26
  class Meta:
28
27
  app_label = 'constec_db'
constec/db/models/erp.py CHANGED
@@ -12,12 +12,10 @@ class System(UUIDModel):
12
12
  description = models.TextField(blank=True, null=True)
13
13
  api_endpoint = models.URLField(max_length=200, blank=True)
14
14
  metadata = models.JSONField(default=dict, blank=True)
15
- created_at = models.DateTimeField(auto_now_add=True, null=True)
16
- updated_at = models.DateTimeField(auto_now=True, null=True)
17
15
 
18
16
  class Meta:
19
17
  app_label = 'constec_db'
20
- db_table = '"erp"."systems"'
18
+ db_table = 'erp"."systems'
21
19
 
22
20
  def __str__(self):
23
21
  return f"{self.name}"
@@ -44,14 +42,11 @@ class CompanySystem(UUIDModel):
44
42
  default=False,
45
43
  help_text="Whether this is the primary ERP system for the company"
46
44
  )
47
- is_active = models.BooleanField(default=True)
48
45
  metadata = models.JSONField(default=dict, blank=True)
49
- created_at = models.DateTimeField(auto_now_add=True)
50
- updated_at = models.DateTimeField(auto_now=True)
51
46
 
52
47
  class Meta:
53
48
  app_label = 'constec_db'
54
- db_table = '"erp"."company_systems"'
49
+ db_table = 'erp"."company_systems'
55
50
  unique_together = [['company', 'system']]
56
51
  indexes = [
57
52
  models.Index(fields=['company', 'is_primary']),
@@ -95,14 +90,11 @@ class Connection(UUIDModel):
95
90
  database = models.CharField(max_length=100)
96
91
  username = models.CharField(max_length=100)
97
92
  encrypted_password = models.TextField()
98
- is_active = models.BooleanField(default=True)
99
93
  last_tested_at = models.DateTimeField(null=True, blank=True)
100
- created_at = models.DateTimeField(auto_now_add=True)
101
- updated_at = models.DateTimeField(auto_now=True)
102
94
 
103
95
  class Meta:
104
96
  app_label = 'constec_db'
105
- db_table = '"erp"."connections"'
97
+ db_table = 'erp"."connections'
106
98
  unique_together = [['system', 'slug']]
107
99
 
108
100
  def __str__(self):
@@ -18,7 +18,7 @@ class Role(UUIDModel):
18
18
 
19
19
  class Meta:
20
20
  app_label = 'constec_db'
21
- db_table = '"erp"."roles"'
21
+ db_table = 'erp"."roles'
22
22
  unique_together = [['system', 'name']]
23
23
 
24
24
  def __str__(self):
@@ -69,7 +69,7 @@ class Entity(UUIDModel):
69
69
 
70
70
  class Meta:
71
71
  app_label = 'constec_db'
72
- db_table = '"erp"."entities"'
72
+ db_table = 'erp"."entities'
73
73
  verbose_name_plural = 'Entities'
74
74
  unique_together = [['company', 'role', 'external_id']]
75
75
  indexes = [
@@ -105,12 +105,6 @@ class EntityAuth(UUIDModel):
105
105
  max_length=255,
106
106
  help_text="Bcrypt hashed password"
107
107
  )
108
- is_active = models.BooleanField(
109
- default=True,
110
- help_text="Whether this account can authenticate"
111
- )
112
- created_at = models.DateTimeField(auto_now_add=True)
113
- updated_at = models.DateTimeField(auto_now=True)
114
108
  last_login = models.DateTimeField(
115
109
  null=True,
116
110
  blank=True,
@@ -119,7 +113,7 @@ class EntityAuth(UUIDModel):
119
113
 
120
114
  class Meta:
121
115
  app_label = 'constec_db'
122
- db_table = '"erp"."entity_auth"'
116
+ db_table = 'erp"."entity_auth'
123
117
  verbose_name = "Entity Authentication"
124
118
  verbose_name_plural = "Entity Authentications"
125
119
 
constec/db/models/flow.py CHANGED
@@ -46,7 +46,6 @@ class FlowTemplate(UUIDModel):
46
46
  default=False,
47
47
  help_text="If true, all organizations can use this template"
48
48
  )
49
- is_active = models.BooleanField(default=True)
50
49
 
51
50
  version = models.CharField(max_length=20, default="1.0.0")
52
51
  created_by = models.ForeignKey(
@@ -55,8 +54,6 @@ class FlowTemplate(UUIDModel):
55
54
  null=True,
56
55
  related_name="created_templates"
57
56
  )
58
- created_at = models.DateTimeField(auto_now_add=True)
59
- updated_at = models.DateTimeField(auto_now=True)
60
57
 
61
58
  class Meta:
62
59
  app_label = 'constec_db'
@@ -108,15 +105,11 @@ class Flow(UUIDModel):
108
105
  help_text="Configuration that merges with template.default_config"
109
106
  )
110
107
 
111
- is_active = models.BooleanField(default=True)
112
108
  is_default = models.BooleanField(
113
109
  default=False,
114
110
  help_text="Whether this is the default flow for the company"
115
111
  )
116
112
 
117
- created_at = models.DateTimeField(auto_now_add=True)
118
- updated_at = models.DateTimeField(auto_now=True)
119
-
120
113
  class Meta:
121
114
  app_label = 'constec_db'
122
115
  db_table = 'constancia"."flows'
@@ -10,7 +10,6 @@ class Module(UUIDModel):
10
10
  slug = models.SlugField(max_length=100, null=True)
11
11
  description = models.TextField(blank=True, null=True)
12
12
  version = models.CharField(max_length=20)
13
- is_active = models.BooleanField(default=True)
14
13
 
15
14
  class Meta:
16
15
  app_label = 'constec_db'
@@ -36,10 +36,7 @@ class Session(UUIDModel):
36
36
  help_text="Session context (connection, role, etc.)"
37
37
  )
38
38
 
39
- is_active = models.BooleanField(default=True)
40
39
  ended_at = models.DateTimeField(null=True, blank=True)
41
- created_at = models.DateTimeField(auto_now_add=True)
42
- updated_at = models.DateTimeField(auto_now=True)
43
40
 
44
41
  class Meta:
45
42
  app_label = 'constec_db'
@@ -79,8 +76,6 @@ class Message(UUIDModel):
79
76
  help_text="Additional message data: tool calls, errors, context, etc."
80
77
  )
81
78
 
82
- created_at = models.DateTimeField(auto_now_add=True)
83
-
84
79
  class Meta:
85
80
  app_label = 'constec_db'
86
81
  db_table = 'constancia"."messages'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: constec
3
- Version: 0.3.4
3
+ Version: 0.4.1
4
4
  Summary: Base library for the Constec ecosystem - shared utilities, models, and namespace foundation
5
5
  License: MIT
6
6
  Project-URL: Homepage, https://github.com/TpmyCT/constec-python
@@ -4,19 +4,22 @@ constec/db/apps.py,sha256=zc-9lGNa049q9bvxV7957EwnZjuBozPLZq594cKAU24,221
4
4
  constec/db/migrations/0001_initial.py,sha256=ru0auCkdz83Qu3e7hGX24WjZXAlM6fE7RZtgAnzANzQ,28979
5
5
  constec/db/migrations/0002_module_level.py,sha256=Es27KUOuI_qrlyL8xBTjwsJJHVduAErNxn4Sdi0a-0w,1526
6
6
  constec/db/migrations/0003_remove_module_level.py,sha256=3GX-VDLSZqqxaZf6KFtuc7U9nCkQ9EF8pSDxOnCz63g,275
7
+ constec/db/migrations/0004_rename_entities_company_cuit_idx_entities_company_e2c50f_idx_and_more.py,sha256=TCkutatVjJhVKxiQwp-RLhBlbOo5rtwSV1qQqao1qCI,11874
8
+ constec/db/migrations/0005_event.py,sha256=kyvEFOAbOJj3daDzOWcIhfXD8gl5EpIHYvRy3880cZc,2892
7
9
  constec/db/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- constec/db/models/__init__.py,sha256=IPh5uRZXtL1iZ54vaM7yBIBVIgx2MjKkgXDAQBJjsDY,2178
9
- constec/db/models/base.py,sha256=1t_eYXYyggoL5fKLcitRPKr1qUE1Ql3_sOmSHQMD3QE,359
10
- constec/db/models/company.py,sha256=9Mr2Q9iSwu4bhp_4KPZqZy4ciJ62rI_AxFWSs1wGGhE,1097
10
+ constec/db/models/__init__.py,sha256=2mRV2cN_UfQLuPwhd93OVg1yCbVuoa6F9GZkXECL8kg,2303
11
+ constec/db/models/automation.py,sha256=4mmZfj-SSIOZLYC2BoMhRsKq0DFn4KperkjJNN3Jfuw,3051
12
+ constec/db/models/base.py,sha256=Urbz9iyOtSxdTfgtEYbtBLmTiea2QAcLq0L40tAzEq8,736
13
+ constec/db/models/company.py,sha256=APYsbiNoqQ-73wxFP0jq3AByHNHn3Jjbe_J_iwpD9gM,1047
11
14
  constec/db/models/contact.py,sha256=VJ66YgzCqp09dzYM5IK9rZZV1jqBepJQO8YK28gA98k,2106
12
- constec/db/models/erp.py,sha256=sN0U0XCMNW-pc9CNLZG_kPZeWXznq_XU3ML2zJ3arjA,3518
13
- constec/db/models/erp_entity.py,sha256=aussrOd7kyNaP2tRJ5SS_WLzpXcZ-SyBa7KnSCkL89g,3954
14
- constec/db/models/flow.py,sha256=K_UA7E4zJ2-UPNp5H9e-lfPeGn0wDEiOl0cRal4Dmb8,4414
15
+ constec/db/models/erp.py,sha256=kTh_MYVwuxS32li2YTCTOgygEVc0UE9CTqnKbfkSkvQ,3060
16
+ constec/db/models/erp_entity.py,sha256=1bV5vhPz89aThKf_YP3YW-baQhSsER04byXnZkwMJd0,3715
17
+ constec/db/models/flow.py,sha256=AdWRCvDo2ZRK_uRbSf-VLZQZ1aVJ-u8X1Ohe9cg3S2M,4093
15
18
  constec/db/models/group.py,sha256=ueCOIfpmzR683ojWf5vLb6IG_jawfVRM7IJcGK05I3Y,897
16
- constec/db/models/module.py,sha256=pKDTdbe0MUZWjgRFS6K1Jo5TMuy9mmdiw7OzrvG_gNw,1969
19
+ constec/db/models/module.py,sha256=z3TYqk0-9VhCYB9eYz-AH1FRSyKnv6aUbnCM6pjGrdA,1919
17
20
  constec/db/models/organization.py,sha256=9dbsh5UBShtDRAeyMqqQEPEaflhzS3aiZpRWUiEluBU,1731
18
21
  constec/db/models/person.py,sha256=B4BNdy2AgqmxrZrkWWvqnFxFHs4uO1n61Y_5sP6MsUo,848
19
- constec/db/models/session.py,sha256=HeIk5rK25IaxKBRX-XNuJ75ndjJZ08rAdSGTLvTwlLE,2695
22
+ constec/db/models/session.py,sha256=CSWiC2Jo2SZnXocy4fQci5qcfLTyaLM2H381iOr6yzg,2477
20
23
  constec/db/models/tag.py,sha256=VlddQW8MLDtYmtt6wp7kC6MsT6SQ6odiJX8mUK8FP3o,1815
21
24
  constec/db/models/user.py,sha256=QHA-BzJ0F1xaeaUfJbuDlmvLDFclSnVrzqN1n4BCumk,2018
22
25
  constec/services/__init__.py,sha256=LXGKIzaRf1gVG2y7oUc18EulUsJXHVs8-oz0nY2h7WA,312
@@ -26,8 +29,8 @@ constec/shared/exceptions.py,sha256=8Bih40RWoH0gVhto09mH2ppSQV_drHPnGWITcoD-0J0,
26
29
  constec/utils/__init__.py,sha256=brf-G4UvU-3CK_rKNPTaHwsVsxnoJSbml_QTZJSM7d0,458
27
30
  constec/utils/cuit.py,sha256=dQKGlA4pRQ5DyR-N4BiV8ZsvAle2Vgjif7PU72zHx_A,2753
28
31
  constec/utils/password.py,sha256=XNpTJ9xZQSoZNjXEAnexAEZuYkwW1dFgX4AY-B5Q0gA,1462
29
- constec-0.3.4.dist-info/licenses/LICENSE,sha256=a1R51ONDGq0UQfV-n3ybsNL7EGhcC2sQ1sXvRANaFVI,1064
30
- constec-0.3.4.dist-info/METADATA,sha256=A8m5zxLysSaSMsU33uBeDbdHfxrNR-h63Ki9ILPKXiY,2954
31
- constec-0.3.4.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
32
- constec-0.3.4.dist-info/top_level.txt,sha256=bQ9AydOLlthShsr7tA7t7ivbLvlLPdhHOo0BdWgnh_Y,8
33
- constec-0.3.4.dist-info/RECORD,,
32
+ constec-0.4.1.dist-info/licenses/LICENSE,sha256=a1R51ONDGq0UQfV-n3ybsNL7EGhcC2sQ1sXvRANaFVI,1064
33
+ constec-0.4.1.dist-info/METADATA,sha256=acMzQCbZfW1kjj-QcE8lRadRUQLfsbg-rRGQWk6ZkpU,2954
34
+ constec-0.4.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
35
+ constec-0.4.1.dist-info/top_level.txt,sha256=bQ9AydOLlthShsr7tA7t7ivbLvlLPdhHOo0BdWgnh_Y,8
36
+ constec-0.4.1.dist-info/RECORD,,