Skip to content

Iteration 2

mijanullah12 edited this page Oct 21, 2026 · 21 revisions

Due: Oct 20, 2026

Planned scope: Research and design

Item Description
AI proposal AI requirements, tools and estimated token usage, to send to the stakeholder.
Meetings Meetings with the stakeholder, the Omerlo CTO and the other companies to validate scope and data access.
Architecture (#28, #29) Data pipeline architecture, system layers and domain diagram. See Overall Architecture and Class Diagrams.
Entity mapping Map the entities from each source to the Unified Data Model.
Onboarding Define the onboarding process.
Verification Check the design and assumptions before development starts.
Tech stack and ADRs (#15) Record decisions D1 to D7 and the library choices. See Architecture Decision Records and Infrastructure and Tools. Moved from Iteration 1.
Personas (#31) Personas that the user story backlog is written for. Moved from Iteration 1.
Problem statement and risks (#32) Problem statement and the risk register. See Risks. Moved from Iteration 1.
Mockups (#30) UI mockups of the dashboard and key screens.
Linter and formatter (#17) Linters, formatters and pre-commit hooks.
CI pipeline (#18) CI runs on every push and pull request. See Testing Plan and Continuous Integration.
Containerization (#19) Run the application with Docker Compose.
Logging and error handling (#20) Central logging and error handling foundation.
Test framework (#21) Test framework, mocking and coverage tooling.
Data cleaning (#103) Implement data cleaning functions to handle missing values, remove duplicates, and standardize data before normalization and further processing.

Tickets

Ticket Title Type Status
#15 Select tech stack and justify frameworks and libraries Spike Open
#17 Configure linters, formatters and pre-commit hooks Task Open
#18 Set up CI pipeline on every push and pull request Task Open
#19 Containerize the application with Docker Compose Task Done
#20 Add central logging and error handling foundation Task Open
#21 Set up test framework, mocking and coverage tooling Task Open
#28 Create the architecture and layer diagram Documentation Open
#29 Create the domain model diagram Documentation Open
#30 Design UI mockups Documentation Open
#31 Write personas and the full user story backlog Documentation Open
#32 Write the problem statement and risk register Documentation Open

Overall summary

Velocity and contractor estimate

  • Planned vs. done:
  • What slipped:
  • Done early:
  • Contractor estimate for this iteration:

Retrospective

  • What went well:
  • What went wrong:
  • Improvements:

Breakdown by individual

Member Contributions (issues / PRs / commits)
Mohamad Addasi (@Moe1177) #29 Create the domain model diagram: ER diagram of data model v1 (tenant, source, sync run, raw record, source record, organization, organization link, match candidate, record change) with relationships and cardinalities, showing tenancy, provenance, versioning, match outcomes and changes between sync runs. Wrote the explanation, glossary and the open questions for #25, and committed the Mermaid source. Published in Overall Architecture and Class Diagrams.
Hendrik Tebeng (@everythingzit) · 40282196 #26 Identifier normalization: clean organization/person names, websites, LinkedIn, emails and phones into one standard form so French and English variants of the same entity can be matched later. Implemented the module and unit tests; documented the business rules and approved libraries on Beyond-CRUD Flows (see also Infrastructure and Tools).
Andrew Ungureanu (@AndrewRazvan) #22 Security baseline (Iteration 3 ticket, started early): PR #82 added Dependabot for GitHub Actions, the backend, the frontend and the Docker images, security headers on every API response (nosniff, frame denial, frame-ancestors 'none', no-referrer, HSTS) and CORS origins set through CORS_ORIGINS, with * rejected, plus 11 unit tests. PR #90 kept Dependabot within the pinned Python and Node runtimes and grouped its PRs, after its first run opened 7 PRs (#83 to #89). Wrote the Security page: threats, secrets and key revocation, API protections and dependency updates.
#18 CI pipeline: PR #80 shows backend and frontend coverage in the CI run summary and adds the synthetic package to backend coverage, so the 50 percent minimum measures about 450 statements instead of 40. Documented each CI check, how to reproduce a failure locally and what is still to add in Testing Plan and Continuous Integration.
Omerlo backoffice API: wrote the Omerlo API page (authentication, workspaces, endpoints, list vs detail, pagination, incremental sync, open questions) and ADR D8, and opened #79 to align the synthetic fixtures with the backoffice shapes (closed by PR #93).
Reviews: approved and merged PR #72 (test framework), with a follow-up note on coverage scope that led to PR #80; approved PR #104 (data cleaning) and the Dependabot updates PR #86, PR #88 and PR #91; approved and merged PR #81 (Fly.io launch config).
Anthony Lim (@antholim) Architecture v2 (#28): drew the PULSE architecture v2 diagram in draw.io after the Omerlo technical sync on Oct 14: external sources (Omerlo API, with the CRM and Le Soleil data still to be decided), scheduler and connectors, raw payload archive, processing pipeline (normalization, entity resolution, snapshot and diff), Postgres as the single source of truth, backend API and dashboard, the search index deferred to Iteration 5 and the optional offline AI layer. It shows the Fly.io hosting and the tenant boundary (Law 25), and notes decisions D1 to D6. Published in Overall Architecture and Class Diagrams with its draw.io source.
#76 Review routing (Iteration 3 ticket, started early): PR #78 makes the team bot ping the Discord role of the team a PR concerns as soon as the PR is ready for review. The team comes from the PR's team label or from the labels of the issue it closes, and every team is pinged when there is none. Each team is pinged once per PR and again if the PR is reopened. The bot can also request reviews on GitHub, and the new /run review-routing [pr] command runs the check on demand. 155 unit tests, 96% coverage.
Team bot hosting: PR #92 keeps the team bot running on Fly.io. Fly stopped the machine because the bot serves no HTTP traffic, so slash commands failed until someone restarted it. The PR also adds a CI job that deploys the bot to Fly after the tests pass on main.
Youssef Yassa (@YoussefYassa7112) #30 Design UI mockups: built an interactive Figma prototype, PULSE · Ecosystem Intelligence — Platform Prototype, with clickable navigation between the PULSE dashboard, the Source & Evidence View, the entity list, the entity profile, the CSV/JSON import screen and the match review queue. Linked it from the wiki Home page. Still to do: name the user story each screen supports, sketch the later-release screens and review them with the sponsor.
#117 PR patch coverage with Codecov: opened the task and PR #118 (merged). Added codecov.yml with a 70 percent patch target, so the codecov/patch check fails when less than 70 percent of the lines a PR adds or changes are covered, while project coverage stays informational and the existing 50 percent minimums stay as they are. The Backend tests job now writes coverage.xml and the Frontend build job an lcov report (new reporter in frontend/vite.config.ts); both upload to Codecov with backend and frontend flags, and Codecov posts one compact comment per PR once both uploads arrive. Verified on the branch: both uploads reached Codecov (98.07 percent total).
Nguyen Le (@KneewYen) Planning meetings: organized and ran the iteration planning meetings to set priorities and split the work across the team.
Product vision: discussed the vision of the product with the team and explained the business side (the client's needs, who PULSE serves and why) so the technical work stays aligned with it.
Implementation research: researched implementation approaches to inform the team's design and tech choices.
Scrum ceremonies: practiced the Scrum ceremonies with the team to keep everyone coordinated and working together.
Wiki history: Iteration 2 page history
Tristan Girardi (@TristanGirardi) #103 Data cleaning and validation (Iteration 4 ticket, started early): PR #104 (merged) added a reusable cleaning module (backend/app/processing/cleaning.py) and per-source rules (cleaning_config.py). It cleans missing values, extra whitespace, Unicode and common encoding errors; converts and validates numbers, French and English booleans, dates, datetimes and emails; checks required fields, numeric ranges and allowed values; maps categories; and finds duplicates within a batch and against stored records. Invalid records are flagged with data quality flags and cleaning statistics, never silently dropped. Added 87 unit tests, with 98 percent coverage of the module. Worked through review feedback from Mohamad, Andrew and Anthony, including date formats from the US and Europe. Mohamad then opened follow-up #106 for Iteration 3 to plug the step into the mappers.
#19 Containerization: PR #48 (merged) added Dockerfiles and .dockerignore files for the frontend and backend, and a compose.yaml that runs either PostgreSQL alone or the full stack, with PostgreSQL 17 on a persistent volume. Also added configuration through .env.example, the FastAPI connection to PostgreSQL with a database health check, the React API service that calls the backend, and uv and Node.js version management (pyproject.toml, uv.lock, .nvmrc) with README run steps. Worked through Anthony's requested changes before approval: switched from pip to uv, kept only npm, and explained why React StrictMode stays.
Project structure: in the same PR, created the initial React frontend and FastAPI backend layout from the system architecture and data pipeline, with one package per layer (api, core, ingestion, processing, models, schemas, services, storage, ai), so later tickets each have a clear place to go.
Youssef Youssef (@Youssef8811) #17 Linters, formatters and pre-commit hooks: PR #49 (merged) set up Ruff for the backend, the Discord bot and scripts/, and ESLint with Prettier for the frontend (lint now fails on any warning). Added pre-commit hooks that run Ruff, Prettier, ESLint and file checks (whitespace, final newline, YAML/TOML/JSON syntax, merge conflict markers, large files) on every commit, plus .editorconfig and .gitattributes so the checks behave the same on Windows, macOS and Linux. Reformatted all existing code to zero lint errors. The linter also caught three bugs: a missing HTTPException import that crashed /health/db instead of returning a 503, uvloop blocking backend installs on Windows, and a missing pythonpath that kept pytest from running. Removed the shared VS Code settings after review. Wrote the Code Style wiki page (style guides, tools, main rules, one-time setup) and linked it from Home and the sidebar.
#18 CI pipeline: PR #75 (merged) added the first GitHub Actions workflow (.github/workflows/ci.yml). It runs on every push and on every PR to main, with five checks: Lint (the same pre-commit hooks), Backend tests (pytest with a throwaway PostgreSQL 17 service), Frontend build, and Docker builds of the backend and frontend images. Runs are cached (npm, uv, pre-commit, Docker layers), and an older run is cancelled when someone pushes again. Added a CI badge to the README and pinned setup-uv to v10.3.0 after Anthony's review so CI could resolve it.
Mijan Ullah (@mijanullah12) #20 Logging and error handling: PR #95 (merged) added structured JSON logging to the backend with structlog: one JSON object per line with the timestamp, level, module, event and a request id (API requests) or run id (syncs and imports), a level set through LOG_LEVEL, and emails, phone numbers and secrets masked before anything is written. Every API response carries an X-Request-ID header, and every request, startup and shutdown is logged. Added a global error handler with custom exceptions (PulseError, DataValidationError, NotFoundError, ConnectorError), so every error returns the same body (code, message, details, request_id); unexpected 500s keep the CORS and security headers and are logged. On the frontend, added a central logger (VITE_LOG_LEVEL), an ApiError type, an ErrorMessage component that shows user-friendly text and an ErrorBoundary that catches render crashes. ESLint now rejects console calls and Ruff rejects print, so all output goes through the loggers. Added backend and frontend unit tests, and wrote the Logging & Error Handling wiki page and the README section.
Reviews: reviewed PR #102 (identifier normalization)

Clone this wiki locally