Extend the ivory and gold palette to shared backend screens and remove conflicting toolbar layout overrides. Correct sidebar action selection and reserve compact sidebar spacing on smaller screens.
Hide the default website header on the 11 pages with custom TNCSC navigation using upgradeable template overrides that preserve edited page content.
Validation: SCSS compilation, JavaScript syntax, sidebar action selection, XML and manifest checks, brand-leak check, and static browser layout checks at four viewport widths passed. Live Odoo verification remains pending because the local Docker engine is unavailable.
Replaces the Phase 7 "content to be finalized" placeholder pages with
TNCSC's actual site content (captured 2026-08-20), verified against a
live Odoo container on a dedicated fresh database (tncsc_site):
- Home, About, About/Tamil Nadu, About/Board of Directors (12 real
members), Membership hub, Membership Benefits, Tamil Class, and
Contact pages, with nav restructured to match tncsc.com's real
structure (About and Membership as dropdowns).
- Real images downloaded from tncsc.com and self-hosted under
static/src/img/ instead of hotlinking the WordPress site.
- Home's "Upcoming Events" and the membership pricing tables are wired
to live event.event / community.membership.tier records instead of
being static copies; Tamil Class links to the real /school/register
flow. One real event seeded (Summer Picnic 2026).
- Deliberately not reproduced: tncsc.com's own Sponsors page and Contact
phone number are unmigrated WordPress theme demo placeholders on the
live site itself (generic client-01..09 logos, a non-Canadian demo
number) - confirmed by inspection, not assumed. Contact page uses the
real, verified email and social links instead.
- post_init_hook now also fixes two Odoo website Copy-On-Write gotchas
that silently prevented the new homepage and nav dropdowns from
rendering at all (auto-forked per-website duplicates winning over
this module's records) - see HANDOFF.md for the full explanation.
Data-only deployment layer seeding TNCSC's branding (navy/orange/electric-
blue from the plan), 5 membership tiers in CAD (Individual $50, Family $80,
Student $20, Senior $30, Life $500 - the plan's own example figures;
update via Settings once TNCSC confirms real pricing), the
'TNCSC-{year}-{seq}' member-ID format, a Canadian (Ontario/HST) chart of
accounts via l10n_ca plus non-profit-specific accounts (Membership Dues/
Event/Sponsorship/School Fees/Donations Revenue, Deferred Event Revenue
liability, a Stripe clearing account) and a Donations journal, bilingual
EN/Tamil overrides of two membership email templates (Tamil text is a
best-effort draft only, explicitly flagged as needing native-speaker
review before go-live), five placeholder website pages (Home/About/Tamil
School/Sponsors/Contact), and TNCSC-named role groups (Board Admin,
Treasurer, Events Officer, School Coordinator, Teacher, Classifieds
Moderator) that imply the existing generic product-layer groups rather
than defining new permission logic.
Chasing the chart-of-accounts setup down to a genuinely working state
took real digging: setting company.country_id on a brand-new company
auto-schedules this Odoo build's own chart-template installer via a
precommit hook (res.company.install_l10n_modules), which races an
explicit try_loading('ca_2023', ...) call made in the same install
transaction and silently replaces its result afterwards (reverting
currency to USD, chart_template to 'generic_coa', and deleting the custom
accounts) - confirmed via raw SQL checks that the correct state exists
right up until the post_init_hook transaction commits, and is gone by the
time the install process exits. Since the precommit auto-trigger only
ever fires once per company (guarded by chart_template being unset), a
second call from a separate transaction is immune to the race. The fix:
the actual setup logic lives in an idempotent res.company._tncsc_setup_
accounting() method (models/res_company.py - a narrow, documented
exception to "no models" in the deployment layer, since cramming this
into a sandboxed ir.cron code string wasn't practical), called as a
best-effort from post_init_hook and guaranteed by a daily safety-net cron
que runs in its own transaction. Also hit two smaller, separate bugs on
the way: ir.cron code execution forbids direct attribute assignment
(STORE_ATTR) in its sandbox, and Html config_parameter fields must not be
wrapped in CDATA in data XML.
Verified end-to-end on a genuinely fresh database (not the long-lived dev
DB, which already has posted entries and correctly refuses a currency
change): installed tncsc_deployment alone, pulling in all 8 product
modules plus l10n_ca as dependencies, confirmed the post-install state via
raw SQL, manually triggered the safety-net cron and confirmed it reached
the fully-correct state (CAD, ca_2023, 355 accounts including all 7
custom ones, the Donations journal, tier products linked to the dues
account), confirmed the cron is idempotent on a second run, and ran the
full test suite (9/9 passing) with the same deterministic setup called
from the test transaction directly.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Scaffolds the CommunityOS monorepo per the implementation plan: 8
brand-neutral product modules (community_theme_base, community_membership,
event_qr_ticketing, community_school, community_classifieds,
community_benefits, community_interac, community_portal) plus the
tncsc_deployment client layer, each with an App-Store-ready manifest,
LGPL-3 license, and empty security/data/demo/tests/views scaffolding.
Adds deploy/docker-compose.yml (Odoo 19 CE + Postgres 16), CI workflow
that installs all modules with --test-enable, and scripts/check_brand_leak.py
+ check_manifests.py enforcing the no-client-identity-in-product-code and
manifest-completeness rules. Verified locally: all 9 modules install clean
on a fresh Odoo 19 database, and the brand-leak check correctly fails when
a client term is added to a product module and passes once removed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>