Skip to content

Commit c381f7b

Browse files
authored
feat: Add demo data for new organizations (#160)
1 parent 76060a1 commit c381f7b

65 files changed

Lines changed: 2095 additions & 2527 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,15 @@ Contains 35 detailed development tasks with:
142142
- flutter_markdown (rich text display)
143143
- file_picker (file uploads)
144144

145+
## Known Dependency Constraints
146+
147+
### retrofit is capped at <4.9.1
148+
`retrofit 4.9.1+` added a `Parser.DartMappable` enum value. `retrofit_generator 9.x` does not handle this value, causing build_runner to fail with a non-exhaustive switch error. The fix requires `retrofit_generator 10.x`, which depends on `build ^4.0.0`. However, `riverpod_generator 2.x` requires `build ^2.0.0`, creating an unresolvable conflict.
149+
150+
**Resolution**: Cap retrofit at `<4.9.1` until the project upgrades to `riverpod_generator 3.x+` (which supports `build ^4.0.0`). The constraint is documented in `pubspec.yaml`.
151+
152+
**To lift this cap**: Upgrade `flutter_riverpod`, `riverpod_annotation`, and `riverpod_generator` to v3+, then upgrade `retrofit_generator` to `^10.2.3` and uncap `retrofit`.
153+
145154
## Testing Approach
146155

147156
- **Widget tests**: In `test/` directory
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""add_is_demo_flag_to_content_models
2+
3+
Revision ID: d9a4adacfa57
4+
Revises: b507803113ba
5+
Create Date: 2026-02-21 09:29:02.017827
6+
7+
"""
8+
from typing import Sequence, Union
9+
10+
from alembic import op
11+
import sqlalchemy as sa
12+
13+
14+
# revision identifiers, used by Alembic.
15+
revision: str = 'd9a4adacfa57'
16+
down_revision: Union[str, Sequence[str], None] = 'b507803113ba'
17+
branch_labels: Union[str, Sequence[str], None] = None
18+
depends_on: Union[str, Sequence[str], None] = None
19+
20+
_tables = [
21+
'activities',
22+
'blockers',
23+
'content',
24+
'lessons_learned',
25+
'portfolios',
26+
'programs',
27+
'projects',
28+
'risks',
29+
'summaries',
30+
'tasks',
31+
]
32+
33+
34+
def upgrade() -> None:
35+
"""Add is_demo boolean column to all content model tables."""
36+
for table in _tables:
37+
op.add_column(table, sa.Column('is_demo', sa.Boolean(), server_default='false', nullable=False))
38+
39+
40+
def downgrade() -> None:
41+
"""Remove is_demo column from all content model tables."""
42+
for table in _tables:
43+
op.drop_column(table, 'is_demo')

backend/models/activity.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from sqlalchemy import Column, String, DateTime, ForeignKey, Text, Enum as SQLEnum
1+
from sqlalchemy import Column, String, DateTime, ForeignKey, Text, Enum as SQLEnum, Boolean
22
from sqlalchemy.dialects.postgresql import UUID
33
from sqlalchemy.orm import relationship
44
import uuid
@@ -30,7 +30,8 @@ class Activity(Base):
3030
timestamp = Column(DateTime, default=datetime.utcnow, nullable=False)
3131
user_id = Column(String(255))
3232
user_name = Column(String(255))
33-
33+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
34+
3435
# Relationships
3536
project = relationship("Project", back_populates="activities")
3637

@@ -44,5 +45,6 @@ def to_dict(self):
4445
"metadata": self.activity_metadata,
4546
"timestamp": self.timestamp.isoformat(),
4647
"user_id": self.user_id,
47-
"user_name": self.user_name
48+
"user_name": self.user_name,
49+
"is_demo": self.is_demo
4850
}

backend/models/blocker.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum, Text, Float, JSON
1+
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum, Text, Float, JSON, Boolean
22
from sqlalchemy.orm import relationship
33
from sqlalchemy.dialects.postgresql import UUID
44
from db.database import Base
@@ -56,6 +56,7 @@ class Blocker(Base):
5656
identified_date = Column(DateTime, default=datetime.utcnow)
5757
last_updated = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
5858
updated_by = Column(String(50)) # 'ai' or 'manual'
59+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
5960

6061
# Relationships
6162
project = relationship("Project", back_populates="blockers")
@@ -84,5 +85,6 @@ def to_dict(self):
8485
"identified_date": self.identified_date.isoformat() if self.identified_date else None,
8586
"last_updated": self.last_updated.isoformat() if self.last_updated else None,
8687
"updated_by": self.updated_by,
87-
"title_embedding": self.title_embedding
88+
"title_embedding": self.title_embedding,
89+
"is_demo": self.is_demo
8890
}

backend/models/content.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class Content(Base):
3232
chunk_count = Column(Integer, default=0, nullable=False)
3333
summary_generated = Column(Boolean, default=False, nullable=False)
3434

35+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
36+
3537
# Metadata for tracking processing status
3638
processed_at = Column(DateTime, nullable=True)
3739
processing_error = Column(Text, nullable=True)

backend/models/lesson_learned.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum, Text, Float, JSON
1+
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum, Text, Float, JSON, Boolean
22
from sqlalchemy.orm import relationship
33
from sqlalchemy.dialects.postgresql import UUID
44
from db.database import Base
@@ -56,6 +56,7 @@ class LessonLearned(Base):
5656
identified_date = Column(DateTime, default=datetime.utcnow)
5757
last_updated = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
5858
updated_by = Column(String(50)) # 'ai' or 'manual'
59+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
5960

6061
# Relationships
6162
project = relationship("Project", back_populates="lessons_learned")
@@ -79,5 +80,6 @@ def to_dict(self):
7980
"identified_date": self.identified_date.isoformat() if self.identified_date else None,
8081
"last_updated": self.last_updated.isoformat() if self.last_updated else None,
8182
"updated_by": self.updated_by,
82-
"title_embedding": self.title_embedding
83+
"title_embedding": self.title_embedding,
84+
"is_demo": self.is_demo
8385
}

backend/models/portfolio.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import uuid
44
from datetime import datetime
5-
from sqlalchemy import Column, String, DateTime, Text, Enum as SQLEnum, ForeignKey
5+
from sqlalchemy import Column, String, DateTime, Text, Enum as SQLEnum, ForeignKey, Boolean
66
from sqlalchemy.dialects.postgresql import UUID
77
from sqlalchemy.orm import relationship
88
import enum
@@ -33,7 +33,8 @@ class Portfolio(Base):
3333
created_by = Column(String(255), nullable=True)
3434
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
3535
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
36-
36+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
37+
3738
# Relationships
3839
programs = relationship("Program", back_populates="portfolio")
3940
projects = relationship("Project", back_populates="portfolio") # Direct projects without a program

backend/models/program.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import uuid
44
from datetime import datetime
5-
from sqlalchemy import Column, String, DateTime, ForeignKey, Text
5+
from sqlalchemy import Column, String, DateTime, ForeignKey, Text, Boolean
66
from sqlalchemy.dialects.postgresql import UUID
77
from sqlalchemy.orm import relationship
88

@@ -22,7 +22,8 @@ class Program(Base):
2222
created_by = Column(String(255), nullable=True)
2323
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
2424
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
25-
25+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
26+
2627
# Relationships
2728
portfolio = relationship("Portfolio", back_populates="programs")
2829
projects = relationship("Project", back_populates="program")

backend/models/project.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import uuid
44
from datetime import datetime
5-
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum as SQLEnum, Text
5+
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum as SQLEnum, Text, Boolean
66
from sqlalchemy.dialects.postgresql import UUID
77
from sqlalchemy.orm import relationship
88
import enum
@@ -29,6 +29,7 @@ class Project(Base):
2929
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
3030
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
3131
status = Column(SQLEnum(ProjectStatus), default=ProjectStatus.ACTIVE, nullable=False)
32+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
3233

3334
# Hierarchy relationships - optional foreign keys
3435
portfolio_id = Column(UUID(as_uuid=True), ForeignKey("portfolios.id", ondelete="SET NULL"), nullable=True)

backend/models/risk.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum, Text, Float, JSON
1+
from sqlalchemy import Column, String, DateTime, ForeignKey, Enum, Text, Float, JSON, Boolean
22
from sqlalchemy.orm import relationship
33
from sqlalchemy.dialects.postgresql import UUID
44
from db.database import Base
@@ -52,6 +52,7 @@ class Risk(Base):
5252
resolved_date = Column(DateTime)
5353
last_updated = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
5454
updated_by = Column(String(50)) # 'ai' or 'manual'
55+
is_demo = Column(Boolean, default=False, nullable=False, server_default="false")
5556

5657
# Relationships
5758
project = relationship("Project", back_populates="risks")
@@ -77,5 +78,6 @@ def to_dict(self):
7778
"resolved_date": self.resolved_date.isoformat() if self.resolved_date else None,
7879
"last_updated": self.last_updated.isoformat() if self.last_updated else None,
7980
"updated_by": self.updated_by,
80-
"title_embedding": self.title_embedding
81+
"title_embedding": self.title_embedding,
82+
"is_demo": self.is_demo
8183
}

0 commit comments

Comments
 (0)