Skip to content

Commit 668326f

Browse files
authored
Merge pull request #597 from lbedner/auth-org-2
Auth Org Phase 2
2 parents 2eefdb5 + 61361f2 commit 668326f

29 files changed

Lines changed: 2456 additions & 263 deletions

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Each generated project includes:
3232

3333
## Installation
3434

35-
**Current Version**: 0.6.7
35+
**Current Version**: 0.6.8rc1
3636

3737
```bash
3838
pip install aegis-stack

aegis/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
Aegis Stack CLI - Component generation and project management tools.
33
"""
44

5-
__version__ = "0.6.7"
5+
__version__ = "0.6.8rc1"

aegis/core/migration_generator.py

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ class ServiceMigrationSpec:
101101
),
102102
ColumnSpec("hashed_password", "sa.String()", nullable=False),
103103
ColumnSpec("last_login", "sa.DateTime()", nullable=True),
104+
ColumnSpec(
105+
"failed_login_attempts", "sa.Integer()", nullable=False, default="0"
106+
),
107+
ColumnSpec("locked_until", "sa.DateTime()", nullable=True),
104108
ColumnSpec("created_at", "sa.DateTime()", nullable=False),
105109
ColumnSpec("updated_at", "sa.DateTime()", nullable=True),
106110
],
@@ -138,7 +142,10 @@ class ServiceMigrationSpec:
138142
ColumnSpec("created_at", "sa.DateTime()", nullable=False),
139143
ColumnSpec("updated_at", "sa.DateTime()", nullable=True),
140144
],
141-
indexes=[IndexSpec("ix_organization_slug", ["slug"], unique=True)],
145+
indexes=[
146+
IndexSpec("ix_organization_name", ["name"]),
147+
IndexSpec("ix_organization_slug", ["slug"], unique=True),
148+
],
142149
),
143150
TableSpec(
144151
name="organization_member",
@@ -169,6 +176,30 @@ class ServiceMigrationSpec:
169176
ForeignKeySpec(["user_id"], "user", ["id"]),
170177
],
171178
),
179+
TableSpec(
180+
name="org_invite",
181+
columns=[
182+
ColumnSpec("id", "sa.Integer()", nullable=False, primary_key=True),
183+
ColumnSpec("organization_id", "sa.Integer()", nullable=False),
184+
ColumnSpec("email", "sa.String()", nullable=False),
185+
ColumnSpec("role", "sa.String()", nullable=False, default="'member'"),
186+
ColumnSpec("invited_by", "sa.Integer()", nullable=False),
187+
ColumnSpec(
188+
"status", "sa.String()", nullable=False, default="'pending'"
189+
),
190+
ColumnSpec("token", "sa.String()", nullable=False),
191+
ColumnSpec("created_at", "sa.DateTime()", nullable=False),
192+
],
193+
indexes=[
194+
IndexSpec("ix_org_invite_email", ["email"]),
195+
IndexSpec("ix_org_invite_org_id", ["organization_id"]),
196+
IndexSpec("ix_org_invite_token", ["token"], unique=True),
197+
],
198+
foreign_keys=[
199+
ForeignKeySpec(["organization_id"], "organization", ["id"]),
200+
ForeignKeySpec(["invited_by"], "user", ["id"]),
201+
],
202+
),
172203
],
173204
)
174205

@@ -378,6 +409,47 @@ class ServiceMigrationSpec:
378409
],
379410
)
380411

412+
AUTH_TOKENS_MIGRATION = ServiceMigrationSpec(
413+
service_name="auth_tokens",
414+
description="Auth token tables (password reset, email verification)",
415+
tables=[
416+
TableSpec(
417+
name="password_reset_token",
418+
columns=[
419+
ColumnSpec("id", "sa.Integer()", nullable=False, primary_key=True),
420+
ColumnSpec("user_id", "sa.Integer()", nullable=False),
421+
ColumnSpec("token", "sa.String()", nullable=False),
422+
ColumnSpec("created_at", "sa.DateTime()", nullable=False),
423+
ColumnSpec("used", "sa.Boolean()", nullable=False, default="'false'"),
424+
],
425+
indexes=[
426+
IndexSpec("ix_password_reset_token_user_id", ["user_id"]),
427+
IndexSpec("ix_password_reset_token_token", ["token"], unique=True),
428+
],
429+
foreign_keys=[
430+
ForeignKeySpec(["user_id"], "user", ["id"]),
431+
],
432+
),
433+
TableSpec(
434+
name="email_verification_token",
435+
columns=[
436+
ColumnSpec("id", "sa.Integer()", nullable=False, primary_key=True),
437+
ColumnSpec("user_id", "sa.Integer()", nullable=False),
438+
ColumnSpec("token", "sa.String()", nullable=False),
439+
ColumnSpec("created_at", "sa.DateTime()", nullable=False),
440+
ColumnSpec("used", "sa.Boolean()", nullable=False, default="'false'"),
441+
],
442+
indexes=[
443+
IndexSpec("ix_email_verification_token_user_id", ["user_id"]),
444+
IndexSpec("ix_email_verification_token_token", ["token"], unique=True),
445+
],
446+
foreign_keys=[
447+
ForeignKeySpec(["user_id"], "user", ["id"]),
448+
],
449+
),
450+
],
451+
)
452+
381453
VOICE_MIGRATION = ServiceMigrationSpec(
382454
service_name="ai_voice",
383455
description="AI voice service table (TTS and STT usage tracking)",
@@ -442,6 +514,7 @@ class ServiceMigrationSpec:
442514
"auth": AUTH_MIGRATION,
443515
"auth_rbac": AUTH_RBAC_MIGRATION,
444516
"auth_org": ORG_MIGRATION,
517+
"auth_tokens": AUTH_TOKENS_MIGRATION,
445518
"ai": AI_MIGRATION,
446519
"ai_voice": VOICE_MIGRATION,
447520
}
@@ -767,6 +840,10 @@ def get_services_needing_migrations(context: dict[str, Any]) -> list[str]:
767840
if include_auth == "yes" or include_auth is True:
768841
services.append("auth")
769842

843+
# Auth token tables (password reset, email verification) - always with auth
844+
if include_auth == "yes" or include_auth is True:
845+
services.append("auth_tokens")
846+
770847
# Auth RBAC columns (rbac or org level)
771848
include_auth_rbac = context.get("include_auth_rbac")
772849
auth_level = context.get("auth_level")

aegis/core/post_gen_tasks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ def _rename_backend_files(suffix: str) -> set[str]:
444444
remove_file(project_path, "app/models/org.py")
445445
remove_file(project_path, "app/services/auth/org_service.py")
446446
remove_file(project_path, "app/services/auth/membership_service.py")
447+
remove_file(project_path, "app/services/auth/invite_service.py")
447448
remove_dir(project_path, "app/components/backend/api/orgs")
448449
remove_file(
449450
project_path,

aegis/templates/copier-aegis-project/{{ project_slug }}/app/cli/migrate_fix.py.jinja

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ from app.i18n import t
2323

2424
{% if include_auth %}
2525
# Import models to register with SQLModel metadata
26-
from app.models.user import User # noqa: F401
26+
from app.models.user import User, PasswordResetToken, EmailVerificationToken # noqa: F401
2727
{% endif %}
2828
{% if include_auth_org %}
29-
from app.models.org import Organization, OrganizationMember # noqa: F401
29+
from app.models.org import Organization, OrganizationMember, OrgInvite # noqa: F401
3030
{% endif %}
3131

3232

0 commit comments

Comments
 (0)