Refonte design : 4 humeurs, onboarding, sections avec boite a outils

- Systeme de themes adaptatifs : Peps (light chaud), Zen (light calme),
  Chagrine (dark violet), Grave (dark ambre) avec CSS custom properties
- Dashboard d'accueil orienté onboarding avec cartes-portes et teaser
  boite a outils
- SectionLayout reutilisable : liste + sidebar toolbox + status pills
  cliquables (En prepa / En vote / En vigueur / Clos)
- ToolboxVignette : vignettes Contexte / Tutos / Choisir / Demarrer
- Seed : Acte engagement certification + forgeron, Runtime Upgrade
  (decision on-chain), 3 modalites de vote (majoritaire, quadratique,
  permanent)
- Backend adapte SQLite (Uuid portable, 204 fix, pool conditionnel)
- Correction noms composants (pathPrefix: false), pinia/nuxt ^0.11

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Yvv
2026-02-28 17:44:48 +01:00
parent 403b94fa2c
commit 77dceb49c3
49 changed files with 20628 additions and 1180 deletions

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, DateTime, func
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy import String, DateTime, JSON, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
@@ -11,8 +10,8 @@ from app.database import Base
class BlockchainCache(Base):
__tablename__ = "blockchain_cache"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
cache_key: Mapped[str] = mapped_column(String(256), unique=True, nullable=False, index=True)
cache_value: Mapped[dict] = mapped_column(JSONB, nullable=False)
cache_value: Mapped[dict] = mapped_column(JSON, nullable=False)
fetched_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False)

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, Integer, Text, DateTime, ForeignKey, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import String, Integer, Text, DateTime, ForeignKey, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
@@ -11,7 +10,7 @@ from app.database import Base
class Decision(Base):
__tablename__ = "decisions"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
title: Mapped[str] = mapped_column(String(256), nullable=False)
description: Mapped[str | None] = mapped_column(Text)
context: Mapped[str | None] = mapped_column(Text)
@@ -28,7 +27,7 @@ class Decision(Base):
class DecisionStep(Base):
__tablename__ = "decision_steps"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
decision_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("decisions.id"), nullable=False)
step_order: Mapped[int] = mapped_column(Integer, nullable=False)
step_type: Mapped[str] = mapped_column(String(32), nullable=False) # qualification, review, vote, execution, reporting

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, Integer, Text, DateTime, ForeignKey, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import String, Integer, Text, DateTime, ForeignKey, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
@@ -11,7 +10,7 @@ from app.database import Base
class Document(Base):
__tablename__ = "documents"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
slug: Mapped[str] = mapped_column(String(128), unique=True, nullable=False, index=True)
title: Mapped[str] = mapped_column(String(256), nullable=False)
doc_type: Mapped[str] = mapped_column(String(64), nullable=False) # licence, engagement, reglement, constitution
@@ -29,7 +28,7 @@ class Document(Base):
class DocumentItem(Base):
__tablename__ = "document_items"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
document_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("documents.id"), nullable=False)
position: Mapped[str] = mapped_column(String(16), nullable=False) # "1", "1.1", "3.2"
item_type: Mapped[str] = mapped_column(String(32), default="clause") # clause, rule, verification, preamble, section
@@ -47,7 +46,7 @@ class DocumentItem(Base):
class ItemVersion(Base):
__tablename__ = "item_versions"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
item_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("document_items.id"), nullable=False)
proposed_text: Mapped[str] = mapped_column(Text, nullable=False)
diff_text: Mapped[str | None] = mapped_column(Text)

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, Integer, Text, DateTime, ForeignKey, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import String, Integer, Text, DateTime, ForeignKey, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
@@ -11,7 +10,7 @@ from app.database import Base
class Mandate(Base):
__tablename__ = "mandates"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
title: Mapped[str] = mapped_column(String(256), nullable=False)
description: Mapped[str | None] = mapped_column(Text)
mandate_type: Mapped[str] = mapped_column(String(64), nullable=False) # techcomm, smith, custom
@@ -29,7 +28,7 @@ class Mandate(Base):
class MandateStep(Base):
__tablename__ = "mandate_steps"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
mandate_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("mandates.id"), nullable=False)
step_order: Mapped[int] = mapped_column(Integer, nullable=False)
step_type: Mapped[str] = mapped_column(String(32), nullable=False) # formulation, candidacy, vote, assignment, reporting, completion, revocation

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, Integer, Float, Boolean, DateTime, ForeignKey, Text, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import String, Integer, Float, Boolean, DateTime, ForeignKey, Text, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
@@ -11,7 +10,7 @@ from app.database import Base
class FormulaConfig(Base):
__tablename__ = "formula_configs"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
name: Mapped[str] = mapped_column(String(128), nullable=False)
description: Mapped[str | None] = mapped_column(Text)
@@ -40,7 +39,7 @@ class FormulaConfig(Base):
class VotingProtocol(Base):
__tablename__ = "voting_protocols"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
name: Mapped[str] = mapped_column(String(128), nullable=False)
description: Mapped[str | None] = mapped_column(Text)
vote_type: Mapped[str] = mapped_column(String(32), nullable=False) # binary, nuanced

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, Integer, Text, DateTime, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import String, Integer, Text, DateTime, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
@@ -11,9 +10,9 @@ from app.database import Base
class SanctuaryEntry(Base):
__tablename__ = "sanctuary_entries"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
entry_type: Mapped[str] = mapped_column(String(64), nullable=False) # document, decision, vote_result
reference_id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), nullable=False)
reference_id: Mapped[uuid.UUID] = mapped_column(Uuid, nullable=False)
title: Mapped[str | None] = mapped_column(String(256))
content_hash: Mapped[str] = mapped_column(String(128), nullable=False) # SHA-256
ipfs_cid: Mapped[str | None] = mapped_column(String(128))

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, Boolean, DateTime, ForeignKey, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import String, Boolean, DateTime, ForeignKey, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
@@ -11,7 +10,7 @@ from app.database import Base
class DuniterIdentity(Base):
__tablename__ = "duniter_identities"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
address: Mapped[str] = mapped_column(String(64), unique=True, nullable=False, index=True)
display_name: Mapped[str | None] = mapped_column(String(128))
wot_status: Mapped[str] = mapped_column(String(32), default="unknown") # member, pending, revoked, unknown
@@ -26,7 +25,7 @@ class DuniterIdentity(Base):
class Session(Base):
__tablename__ = "sessions"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
token_hash: Mapped[str] = mapped_column(String(128), unique=True, nullable=False, index=True)
identity_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("duniter_identities.id"), nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())

View File

@@ -1,8 +1,7 @@
import uuid
from datetime import datetime
from sqlalchemy import String, Integer, Float, Boolean, Text, DateTime, ForeignKey, func
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import String, Integer, Float, Boolean, Text, DateTime, ForeignKey, Uuid, func
from sqlalchemy.orm import Mapped, mapped_column, relationship
from app.database import Base
@@ -11,7 +10,7 @@ from app.database import Base
class VoteSession(Base):
__tablename__ = "vote_sessions"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
decision_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("decisions.id"))
item_version_id: Mapped[uuid.UUID | None] = mapped_column(ForeignKey("item_versions.id"))
voting_protocol_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("voting_protocols.id"), nullable=False)
@@ -49,7 +48,7 @@ class VoteSession(Base):
class Vote(Base):
__tablename__ = "votes"
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
id: Mapped[uuid.UUID] = mapped_column(Uuid, primary_key=True, default=uuid.uuid4)
session_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("vote_sessions.id"), nullable=False)
voter_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("duniter_identities.id"), nullable=False)
vote_value: Mapped[str] = mapped_column(String(32), nullable=False) # for, against, or nuanced levels