Skip to content

Commit fc71819

Browse files
authored
feat(phonebook): use modular association groupements (#759)
### Description Please explain the changes you made here. ### Checklist - [ ] Created tests which fail without the change (if possible) - [ ] All tests passing - [ ] Extended the documentation, if necessary
1 parent 8bc4861 commit fc71819

10 files changed

Lines changed: 1340 additions & 303 deletions

File tree

app/modules/phonebook/cruds_phonebook.py

Lines changed: 344 additions & 80 deletions
Large diffs are not rendered by default.

app/modules/phonebook/endpoints_phonebook.py

Lines changed: 266 additions & 92 deletions
Large diffs are not rendered by default.

app/modules/phonebook/factory_phonebook.py

Lines changed: 59 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,92 @@
11
import random
22
import uuid
33

4+
from faker import Faker
45
from sqlalchemy.ext.asyncio import AsyncSession
56

7+
from app.core.groups.factory_groups import CoreGroupsFactory
68
from app.core.users import cruds_users
79
from app.core.users.factory_users import CoreUsersFactory
810
from app.core.utils.config import Settings
9-
from app.modules.phonebook import cruds_phonebook, models_phonebook
10-
from app.modules.phonebook.types_phonebook import Kinds, RoleTags
11+
from app.modules.phonebook import cruds_phonebook, schemas_phonebook
12+
from app.modules.phonebook.types_phonebook import RoleTags
1113
from app.types.factory import Factory
1214

15+
faker = Faker("fr_FR")
16+
1317

1418
class PhonebookFactory(Factory):
15-
depends_on = [CoreUsersFactory]
19+
depends_on = [CoreUsersFactory, CoreGroupsFactory]
1620

1721
@classmethod
18-
async def create_association(cls, db: AsyncSession):
19-
association_id_1 = str(uuid.uuid4())
20-
await cruds_phonebook.create_association(
21-
association=models_phonebook.Association(
22-
id=association_id_1,
23-
name="Eclair",
24-
description="L'asso d'informatique la plus cool !",
25-
deactivated=False,
26-
kind=Kinds.section_ae,
27-
mandate_year=2025,
22+
async def create_association_groupement(cls, db: AsyncSession) -> list[uuid.UUID]:
23+
groupement_ids = [uuid.uuid4() for _ in range(3)]
24+
await cruds_phonebook.create_groupement(
25+
schemas_phonebook.AssociationGroupement(
26+
id=groupement_ids[0],
27+
name="Section AE",
28+
manager_group_id=CoreGroupsFactory.groups_ids[0],
2829
),
2930
db=db,
3031
)
31-
32-
await cruds_phonebook.create_membership(
33-
membership=models_phonebook.Membership(
34-
id=str(uuid.uuid4()),
35-
user_id=CoreUsersFactory.demo_users_id[0],
36-
association_id=association_id_1,
37-
mandate_year=2025,
38-
role_name="Prez",
39-
role_tags=RoleTags.president.name,
40-
member_order=1,
32+
await cruds_phonebook.create_groupement(
33+
schemas_phonebook.AssociationGroupement(
34+
id=groupement_ids[1],
35+
name="Club AE",
36+
manager_group_id=CoreGroupsFactory.groups_ids[0],
4137
),
4238
db=db,
4339
)
44-
45-
association_id_2 = str(uuid.uuid4())
46-
await cruds_phonebook.create_association(
47-
association=models_phonebook.Association(
48-
id=association_id_2,
49-
name="Association 2",
50-
description="Description de l'asso 2",
51-
associated_groups=[],
52-
deactivated=False,
53-
kind=Kinds.section_use,
54-
mandate_year=2025,
40+
await cruds_phonebook.create_groupement(
41+
schemas_phonebook.AssociationGroupement(
42+
id=groupement_ids[2],
43+
name="Section USE",
44+
manager_group_id=CoreGroupsFactory.groups_ids[1],
5545
),
5646
db=db,
5747
)
58-
users = await cruds_users.get_users(db=db)
59-
tags = list(RoleTags)
60-
for i, user in enumerate(random.sample(users, 10)):
61-
await cruds_phonebook.create_membership(
62-
membership=models_phonebook.Membership(
63-
id=str(uuid.uuid4()),
64-
user_id=user.id,
65-
association_id=association_id_2,
48+
return groupement_ids
49+
50+
@classmethod
51+
async def create_association(
52+
cls,
53+
db: AsyncSession,
54+
groupement_ids: list[uuid.UUID],
55+
):
56+
for i in range(5):
57+
association_id = str(uuid.uuid4())
58+
await cruds_phonebook.create_association(
59+
association=schemas_phonebook.AssociationComplete(
60+
id=association_id,
61+
groupement_id=groupement_ids[i % len(groupement_ids)],
62+
name=faker.company(),
63+
description="Description de l'association",
64+
associated_groups=[],
65+
deactivated=False,
6666
mandate_year=2025,
67-
role_name=f"VP {i}",
68-
role_tags=tags[i].name if i < len(tags) else "",
69-
member_order=i,
7067
),
7168
db=db,
7269
)
70+
users = await cruds_users.get_users(db=db)
71+
tags = list(RoleTags)
72+
for j, user in enumerate(random.sample(users, 10)):
73+
await cruds_phonebook.create_membership(
74+
membership=schemas_phonebook.MembershipComplete(
75+
id=str(uuid.uuid4()),
76+
user_id=user.id,
77+
association_id=association_id,
78+
mandate_year=2025,
79+
role_name=f"VP {j}",
80+
role_tags=tags[j].name if j < len(tags) else "",
81+
member_order=j,
82+
),
83+
db=db,
84+
)
7385

7486
@classmethod
7587
async def run(cls, db: AsyncSession, settings: Settings) -> None:
76-
await cls.create_association(db)
88+
groupement_ids = await cls.create_association_groupement(db=db)
89+
await cls.create_association(db, groupement_ids=groupement_ids)
7790

7891
@classmethod
7992
async def should_run(cls, db: AsyncSession):

app/modules/phonebook/models_phonebook.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from typing import TYPE_CHECKING
2+
from uuid import UUID
23

34
from sqlalchemy import ForeignKey
45
from sqlalchemy.orm import Mapped, mapped_column, relationship
56

6-
from app.modules.phonebook.types_phonebook import Kinds
7-
from app.types.sqlalchemy import Base
7+
from app.types.sqlalchemy import Base, PrimaryKey
88

99
if TYPE_CHECKING:
1010
from app.core.groups.models_groups import CoreGroup
@@ -31,13 +31,24 @@ class Membership(Base):
3131
member_order: Mapped[int]
3232

3333

34+
class AssociationGroupement(Base):
35+
__tablename__ = "phonebook_association_groupement"
36+
37+
id: Mapped[PrimaryKey]
38+
manager_group_id: Mapped[str] = mapped_column(ForeignKey("core_group.id"))
39+
name: Mapped[str] = mapped_column(index=True, unique=True)
40+
41+
3442
class Association(Base):
3543
__tablename__ = "phonebook_association"
3644

3745
id: Mapped[str] = mapped_column(primary_key=True, index=True)
3846
name: Mapped[str] = mapped_column(index=True)
3947
description: Mapped[str | None]
40-
kind: Mapped[Kinds]
48+
groupement_id: Mapped[UUID] = mapped_column(
49+
ForeignKey("phonebook_association_groupement.id"),
50+
index=True,
51+
)
4152
mandate_year: Mapped[int]
4253
deactivated: Mapped[bool]
4354
associated_groups: Mapped[list["CoreGroup"]] = relationship(

app/modules/phonebook/schemas_phonebook.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from uuid import UUID
2+
13
from pydantic import BaseModel, ConfigDict
24

35
from app.core.users.schemas_users import CoreUserSimple
4-
from app.modules.phonebook.types_phonebook import Kinds
56

67

78
class RoleTagsReturn(BaseModel):
@@ -19,7 +20,7 @@ class RoleTagsBase(BaseModel):
1920

2021
class AssociationBase(BaseModel):
2122
name: str
22-
kind: Kinds
23+
groupement_id: UUID
2324
mandate_year: int
2425
description: str | None = None
2526
associated_groups: list[str] = [] # Should be a list of ids
@@ -34,7 +35,7 @@ class AssociationComplete(AssociationBase):
3435

3536
class AssociationEdit(BaseModel):
3637
name: str | None = None
37-
kind: Kinds | None = None
38+
groupement_id: UUID | None = None
3839
description: str | None = None
3940
mandate_year: int | None = None
4041

@@ -48,7 +49,7 @@ class MembershipBase(BaseModel):
4849
association_id: str
4950
mandate_year: int
5051
role_name: str
51-
role_tags: str | None = None # "roletag1;roletag2;..."
52+
role_tags: str = "" # "roletag1;roletag2;..."
5253
member_order: int
5354

5455
model_config = ConfigDict(from_attributes=True)
@@ -80,5 +81,14 @@ class MemberComplete(MemberBase):
8081
model_config = ConfigDict(from_attributes=True)
8182

8283

83-
class KindsReturn(BaseModel):
84-
kinds: list[Kinds]
84+
class AssociationGroupementBase(BaseModel):
85+
name: str
86+
manager_group_id: str
87+
88+
model_config = ConfigDict(from_attributes=True)
89+
90+
91+
class AssociationGroupement(AssociationGroupementBase):
92+
id: UUID
93+
94+
model_config = ConfigDict(from_attributes=True)

app/modules/phonebook/types_phonebook.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,3 @@ class RoleTags(Enum):
77
treso = "Trez'"
88
resp_co = "Respo Com'"
99
resp_part = "Respo Partenariats"
10-
11-
12-
class Kinds(Enum):
13-
comity = "Comité"
14-
section_ae = "Section AE"
15-
club_ae = "Club AE"
16-
section_use = "Section USE"
17-
club_use = "Club USE"
18-
association_independant = "Asso indé"
24.3 KB
Loading

0 commit comments

Comments
 (0)