# Cloud-Managed Themes — Application Structures

> **Working-copy status:** The presentation is being simplified to match the familiar CSS showcase template. Sections 1, 2, 3, and 6 are locked unchanged. Section 4 restores a multi-step AI Prompt workflow; Sections 5 and 7 become concise Audit and Verification sections. Master prompts, runtime, backend, and publication remain unchanged. Current results are recorded separately; earlier approvals are historical.

A real Supabase-backed configuration feature added to an existing static resume. Cloudflare continues delivering the website; a browser-side read retrieves menu order and defaults, while seven existing local packages remain the renderers.

## Application Architecture presentation

The page keeps its existing Problem & Scope, Architecture Concepts, System Architecture, and Working System sections. The remaining sections follow the simpler CSS-template rhythm: **AI Prompt → Audit → Verification**.

AI Prompt explains four practical steps—Review, Plan, Build, Verify—with optional copyable suggested prompts and the existing full implementation specification. These are reusable suggestions, not an invented historical transcript. The original AI-request appendix remains unchanged.

The audit contains the existing SQL reference and four short checks. Verification is a brief checklist linking to [actual revision results](../../docs/cloud-theme-qa/architecture-presentation-verification.md). Detailed evidence and limitations stay in that report, not additional card grids.

All existing theme compatibility hooks and live controllers remain in place. Master-prompt work is deferred until the user is satisfied with this presentation.

## Target system and scope

**System analyzed:** Supabase, an open-source composition of services centered on PostgreSQL. The relevant path is the browser → Supabase API/PostgREST → PostgreSQL. A publishable key identifies the public API client. Database grants restrict available operations, and RLS restricts visible rows.

**This prototype uses:** the REST Data API, PostgreSQL, SELECT grants, RLS, and browser storage.

**Not implemented:** visitor authentication, cross-device preference sync, remote CSS/assets, a public settings editor, Storage, Realtime, Edge Functions, or a self-hosted full Supabase stack. The architecture map is explanatory; browser request data is not internal gateway/database telemetry.

## Components and ownership

| Component | Responsibility |
|---|---|
| Cloudflare / existing static host | Website delivery and asset caching; unchanged during local development |
| `theme-cloud-config.js` | Public project URL and publishable browser key |
| `theme-cloud.js` | Validated read, timeout, latest-request ownership, cache/fallback, preference precedence |
| `theme.js` | Existing local stylesheet, assets, icon metadata, mode, and saved-preference controller |
| `site-navigation.js` | Existing menu markup, now ordered by validated configuration |
| `styles/themes/*` | Existing CSS, theme metadata, textures, icons; unchanged |
| `public.portfolio_theme_settings` | Exactly one record, `id = 'portfolio'` |
| `showcase.js` | Live observations and controls; shares the service and renderer |

### Preference and failure rules

1. HTML and local theme code render immediately; Supabase does not block the page.
2. Each valid saved preference takes precedence independently: a saved mode does not require a saved family, or vice versa.
3. Cloud defaults are applied without saving them as visitor choices.
4. Theme previews and mode changes explicitly save the visitor choice.
5. A selection made during a pending fetch must not be overwritten by the response.
6. Superseded fetches are aborted and cannot replace newer state.
7. Requests time out after six seconds. Failure uses validated cached settings, then bundled defaults if no valid cache exists.
8. The cache is a last-known configuration, not an assertion that Supabase is currently reachable. Its age is not an authorization boundary; it remains usable until the next successful read.
9. Unknown IDs, invalid modes, missing/duplicate order entries, and empty/duplicate result rows are rejected.
10. Offline simulation skips the request and is labeled as simulation, with no invented HTTP status or network timing.

A fresh browser starts from bundled styling, so a newly fetched default can cause a brief appearance change. This is the deliberate non-blocking trade-off rather than hiding the resume until the network returns. Cache is applied after the shared controller initializes, not a promise of zero-flash first paint.

## Local setup

From the **Resume** directory:

```bash
python -m http.server 8768 --bind 127.0.0.1
```

Open:

- Resume: `http://127.0.0.1:8768/resume.html`
- Showcase: `http://127.0.0.1:8768/showcases/cloud-managed-themes/index.html`

Use HTTP, not `file://`: browser origins, API requests, and persistence should be exercised under a real origin.

## Database setup

The dedicated project is **AD371-Theme-System**, separate from earlier class databases.

1. Sign in to Supabase yourself. Keep passwords and verification codes private.
2. Open the dedicated project's SQL Editor.
3. Run [`setup.sql`](setup.sql).
4. Confirm one row, RLS enabled, SELECT allowed, and writes denied for `anon` and `authenticated`.
5. Use only the **publishable** key from the project's API Keys page in `theme-cloud-config.js`.

The setup script is transactional and rerunnable. It seeds a missing row but does not overwrite later settings edits. The named policy replacement affects only this table's read policy. Never substitute a secret/service-role key in the frontend.

### Manage settings after setup

An administrator can edit the one row in Supabase's Table Editor or SQL Editor. No public frontend write path exists. For example, this administrative change makes Luminous Midnight dark the default and first menu entry:

```sql
update public.portfolio_theme_settings
set default_theme = 'luminous-midnight',
    default_mode = 'dark',
    theme_order = array[
      'luminous-midnight', 'standard', 'playful-pop', 'raggedy-granite',
      'glossy-marble', 'gothic-stickerboard', 'baroque-plexiglas'
    ]::text[]
where id = 'portfolio';
```

This is a documented example, **not a claim that the default has been changed**. Existing visitors retain saved preferences. After an authorized edit, use a fresh browser profile or the showcase's “Use cloud defaults in this browser” control and reload configuration.

## Repository and deployment status

This feature is developed in **Week8**, copied and hash-verified from Week7. Week7 and the existing `chernichenkodmitriy.com` deployment are unchanged. Local presentation approval, GitHub publication, the hosting build, and the served domain are separate checkpoints. The existing private `Chernichenko-Dmitriy/Chernichenko-Dmitriy.github.io` source repository is retained; `AD371` is a proposed USB course-folder label, not a request to create a repository. This update does not publish the local changes.

For Cloudflare Pages, this is a static site: no new build framework or worker is required. Publish the directory containing `index.html`, `resume.html`, controllers, styles, assets, and showcases. Do not publish `.git`, private working directories, or credentials. If a Content Security Policy is present, its `connect-src` must permit `https://iubbxotkeplkecdhuzke.supabase.co`. Preview and production must be checked separately for origin policy, caching, and real requests.

## AI collaboration

See [`AI-PROMPTS.md`](AI-PROMPTS.md) for verbatim primary user requests, ownership disclosure, and genuine corrections. The on-page expandable implementation specification is explicitly identified as a derived requirements summary, not an invented transcript or prompt sent to another model.

The old master prompt was copied into Week8 without editing. The showcase uses its Architecture-specific section contract and official Supabase sources where MDN does not document the service. Its familiar chrome and theme compatibility hooks are retained from the existing portfolio; the Architecture diagram, decisions, and failure explanations replace CSS-specific section internals.

## Executed verification and evidence

- Real REST read returned **HTTP 200** and the actual configuration row.
- INSERT, UPDATE, and DELETE permission probes were denied with **HTTP 401 / PostgreSQL 42501**, using an impossible-row filter or invalid test ID to avoid changing configuration even if a permission error were discovered.
- Dashboard SQL result showed RLS enabled; SELECT allowed; writes denied for both browser roles.
- Unit tests were run RED (20 failed before implementation), then GREEN (20 passed).
- Initial Chromium inspection showed seven sections, seven themes, no page errors, no HTTP asset failures, and no desktop page overflow.
- Visual inspection identified and corrected JSON-panel contrast by reusing existing theme-owned code styling.

The full browser run passed **22 scenarios across Chromium and Firefox**, including all seven themes in both modes, live connections, controlled failure/race cases, keyboard preview activation, and widths down to 320px. The repository-contained tests were then exercised again with the same passing results. See [`../../docs/cloud-theme-qa/README.md`](../../docs/cloud-theme-qa/README.md) and its machine-readable results for executed evidence.

This is not a full accessibility certification or a production-deployment check. Browser fixtures used to test alternate defaults and failures are labeled as **controlled test responses**, not live Supabase data.

## Sources

Checked during implementation:

- [Supabase architecture](https://supabase.com/docs/guides/getting-started/architecture)
- [Supabase RLS](https://supabase.com/docs/guides/database/postgres/row-level-security)
- [Supabase API keys](https://supabase.com/docs/guides/getting-started/api-keys)
- [Cloudflare Pages static HTML](https://developers.cloudflare.com/pages/framework-guides/deploy-anything)
- [MDN fetch](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch)
- [MDN localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage)
- [MDN AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController)
- [MDN CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/--*)

## Reflection and walkthrough outline

The existing portfolio already separates shared controllers from theme-owned CSS and assets. Adding Supabase as a data source preserves that boundary instead of replacing it. It is a narrow companion proof of concept for a much larger open-source architecture, not a clone of Supabase.

For a 5–7 minute screen-and-camera walkthrough: explain the two delivery paths; show the actual database row and read-only contract; reload and inspect real request observations; preview a theme and verify persistence; demonstrate labeled fallback and filtering; resize and show DevTools; finish with the trade-off between administrative flexibility and a new network dependency. Camera framing, recording, public URLs, and course submission remain student tasks and must be verified before recording.
