# CyberHybridHub - Website Goals and Services ## Overview CyberHybridHub is a comprehensive web platform designed to serve two primary purposes: providing free financial calendar services and offering a dedicated portal for rental property management. This repo implements the rental property portal as a Fresh (Deno) web app with landlord and tenant flows, a lightweight in-memory E2E test mode, and a Playwright test suite designed to be deterministic and repeatable. ## Primary Services ### 1. Free Financial Calendar Services Our platform offers complimentary financial calendar tools designed to help users: - Track important financial dates and deadlines - Monitor payment schedules and due dates - Plan for financial events and obligations - Stay organized with customizable calendar views - Receive notifications for upcoming financial milestones These services are provided at no cost to ensure financial planning tools are accessible to everyone. ### 2. Rental Management Portal CyberHybridHub serves as a centralized hub for rental property management, connecting: #### For Renters: - **Payment Management**: Secure online rent payments and transaction history - **Service Requests**: Submit and track maintenance requests - **Communication**: Direct messaging with landlords and property managers - **Document Management**: Access lease agreements, receipts, and important documents - **Payment Reminders**: Automated notifications for upcoming rent payments #### For Landlords: - **Rent Collection**: Streamlined payment processing and tracking - **Property Management**: Organize multiple properties and units - **Tenant Communication**: Centralized messaging and announcements - **Maintenance Coordination**: Efficient service request management - **Financial Reporting**: Revenue tracking and expense management - **Document Storage**: Secure storage for leases, inspections, and records ## Key Features ### Security & Privacy - Encrypted data transmission and storage - Secure payment processing - User authentication and access controls - Privacy-focused design ### User Experience - Intuitive dashboard for both renters and landlords - Mobile-responsive design - Real-time notifications and updates - Easy navigation and clean interface ### Integration - Calendar synchronization with personal devices - Payment gateway integration - Email and SMS notifications - Document upload and management system ## Mission Statement CyberHybridHub aims to simplify financial planning and rental management by providing free, accessible tools that empower users to take control of their financial obligations while fostering better communication and efficiency in the rental market. ## Target Audience - Individual renters seeking better payment and service management - Landlords and property managers looking for streamlined operations - Anyone interested in free financial planning and calendar tools - Property management companies seeking efficient digital solutions ## Technology Stack Built with modern web technologies to ensure reliability, security, and scalability: - Frontend: Responsive web interface - Backend: Secure API and database management - Payment Processing: Industry-standard payment gateways - Security: End-to-end encryption and best practices ## App Architecture Summary (Rental Portal) - **Core flows**: onboarding (landlord + tenant), dashboards, properties, leases, maintenance, messages, payments, documents, reminders, portfolio/multi-property. - **Routing**: UI pages live under `routes/` (e.g., `routes/landlord/*`, `routes/tenant/*`, `routes/onboarding/*`), API endpoints under `routes/api/*`. - **Services**: business logic in `services/*`. When `E2E_TEST=true`, services read/write deterministic fixtures from `services/e2eFixtures.ts` instead of the database. - **Auth in tests**: E2E mode accepts a header `x-e2e-user` to bypass auth (`services/stateMiddleware.ts`), and UI tests set a skip-encryption flag via `tests/e2e/helpers.ts`. ## Developer Quick Start For project-specific architecture/testing/cleanup guidance, see: - `CLAUDE.md` -> `CYBERHYBRIDHUB PROJECT RUNBOOK` Recommended local flow: 1. Start DB: `docker compose up -d` 2. Verify DB wiring: `deno run -A test-db-connection.ts` 3. Run Docker-backed auth callback regression test: `deno task test:auth-callback-db` 4. Run Playwright suite: `deno task e2e` Notes: - `deno task test:auth-callback-db` uses `tests/run-auth-callback-db-test.sh` and includes `newgrp docker && ...`. - That runner auto-cleans containers and auth regression records after the run. - If a run is interrupted, run `deno run -A tests/integration/cleanup-auth-callback-records.ts` then `docker compose down --remove-orphans`. ## Deterministic E2E Testing (Playwright) The goal is to always verify functional behavior without flakiness or state drift. ### How E2E Mode Works - **E2E env**: `E2E_TEST=true` enables fixture-backed services (`services/e2eFixtures.ts`). - **Auth bypass**: use `x-e2e-user` header (values like `landlord`, `tenant`, `landlord-onboarding`) to map to fixture users. - **Deterministic time**: `applyDeterministicPage()` stubs `Date.now()` and `Math.random()` and disables animations. - **Encryption bypass**: `useE2EUser()` sets `globalThis.__E2E_SKIP_ENCRYPTION__` and a localStorage flag to keep test data readable. - **Web server**: Playwright config uses `deno task dev` with `E2E_TEST=true` and a fixed base URL. ### Writing / Updating `tests/e2e/*` - Prefer **resilient assertions** (e.g., check for a section header or a state-dependent branch) because E2E data can be mutated across tests. - When adding UI flows, make sure the corresponding service uses E2E fixtures (or add fixture support in `services/e2eFixtures.ts`). - Use `applyDeterministicPage()` and `useE2EUser()` at the start of each UI test. - Use `e2eHeaders()` for API-level tests to route through the E2E user context. - If a flow writes data (create/update), the fixture state persists for the rest of the run. Avoid assuming pristine state unless you add explicit resets. ### Available Test Methodologies (Deterministic Playwright) - **UI E2E (browser)**: `page.goto(...)` + user interactions + assertions on UI outcomes. - **API E2E**: `request.get/post(...)` with `e2eHeaders(...)` for deterministic API coverage without UI. - **Hybrid E2E**: create data via API, validate via UI (or vice versa) for full-stack coverage. ### Running Tests - `deno task e2e` (uses Playwright + deterministic server config from `playwright.config.ts`). ## Future Development Planned enhancements include: - Advanced financial analytics and reporting - Mobile applications for iOS and Android - Integration with accounting software - Expanded property management features - AI-powered financial insights and recommendations # Fresh project Your new Fresh project is ready to go. You can follow the Fresh "Getting Started" guide here: https://fresh.deno.dev/docs/getting-started ### Usage Make sure to install Deno: https://docs.deno.com/runtime/getting_started/installation Then start the project in development mode: ``` deno task dev ``` deno run -A -r jsr:@fresh/update deno compile -A --target x86_64-unknown-linux-gnu --include ./_fresh/client --output ../server ./compiled-entry.js deno compile -A --target x86_64-pc-windows-msvc --include ./_fresh/client --output ../server.exe ./_fresh/compiled-entry.js deno compile -A --target x86_64-apple-darwin --include ./_fresh/client --output ./server ./_fresh/compiled-entry.js docker login cyberhybridhubreg.azurecr.io docker pull cyberhybridhubreg.azurecr.io/cyberhybridhub:latest docker run -it -p 8080:8080 cyberhybridhubreg.azurecr.io/cyberhybridhub:latest tail -f /dev/null az acr import --name cyberhybridhub --source denoland/deno:latest --image denoland/deno:latest CMD ["tail", "-f", "/bin/bash] ENTRYPOINT ["dotnet", "DotNet.Docker.dll"] docker build -t app . && docker run -it -p 8080:8080 app docker commit confident_lederberg cyberhybridhub/deno2.5.4-dotnet8.0.414:latest docker login cyberhybridhub.azurecr.io docker tag cyberhybridhub/deno2.5.4-dotnet8.0.414:latest cyberhybridhub.azurecr.io/deno2.5.4-dotnet8.0.414:latest docker push cyberhybridhub.azurecr.io/deno2.5.4-dotnet8.0.414:latest docker build -t app3 . && docker run -it -p 8080:8080 app3 sh apt-get update RUN if ! command -v git; then\ apt-get update && apt-get install -y git;\ fi && git --version docker run -d -p 8080:80 --name myapp --entrypoint "dotnet" cyberhybridhub.azurecr.io/dotnet/aspnet:8.0-alpine .dll apt-get update apt-get install -y wget apt-transport-https wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb mkdir -p /tmp/deno-compile-server && ln -sfn "$(pwd)/server" /tmp/deno-compile-server/server && dotnet AzureFront.CyberHybridHub.dll 2025-10-16T13:19:46.1385179Z NotFound: path not found: stat '/tmp/deno-compile-server/_fresh/client\assets\client-entry-DNH4ZUpx.css' 2025-10-16T13:19:46.1385699Z at Object.stat (ext:deno_fs/30_fs.js:425:21) 2025-10-16T13:19:46.1385787Z at ProdBuildCache.readFile (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:5279:50) 2025-10-16T13:19:46.1385814Z at freshServeStaticFiles (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:5835:35) 2025-10-16T13:19:46.1385839Z at Context.fn (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4403:34) 2025-10-16T13:19:46.1385862Z at segmentMiddleware (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4588:26) 2025-10-16T13:19:46.1385885Z at fn (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4403:34) 2025-10-16T13:19:46.1385908Z at file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4419:20 2025-10-16T13:19:46.1385934Z at NoopContextManager.with (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:981:15) 2025-10-16T13:19:46.1385957Z at ContextAPI.with (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:1048:42) 2025-10-16T13:19:46.1385981Z at NoopTracer.startActiveSpan (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:1328:27) { 2025-10-16T13:19:46.1386002Z name: "NotFound", 2025-10-16T13:19:46.1386056Z code: "ENOENT" 2025-10-16T13:19:46.1386076Z } 2025-10-16T13:19:46.8441754Z NotFound: path not found: stat '/tmp/deno-compile-server/_fresh/client\assets\client-entry-9ekbL4RI.js' 2025-10-16T13:19:46.8442151Z at Object.stat (ext:deno_fs/30_fs.js:425:21) 2025-10-16T13:19:46.8442187Z at ProdBuildCache.readFile (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:5279:50) 2025-10-16T13:19:46.8442212Z at freshServeStaticFiles (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:5835:35) 2025-10-16T13:19:46.8442242Z at Context.fn (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4403:34) 2025-10-16T13:19:46.8442269Z at segmentMiddleware (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4588:26) 2025-10-16T13:19:46.8442291Z at fn (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4403:34) 2025-10-16T13:19:46.8442364Z at file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4419:20 2025-10-16T13:19:46.844239Z at NoopContextManager.with (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:981:15) 2025-10-16T13:19:46.8442414Z at ContextAPI.with (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:1048:42) 2025-10-16T13:19:46.8442438Z at NoopTracer.startActiveSpan (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:1328:27) { 2025-10-16T13:19:46.8442458Z name: "NotFound", 2025-10-16T13:19:46.8442477Z code: "ENOENT" 2025-10-16T13:19:46.8442497Z } 2025-10-16T13:19:49.120541Z NotFound: path not found: stat '/tmp/deno-compile-server/_fresh/client\favicon.ico' 2025-10-16T13:19:49.1205856Z at Object.stat (ext:deno_fs/30_fs.js:425:21) 2025-10-16T13:19:49.1205895Z at ProdBuildCache.readFile (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:5279:50) 2025-10-16T13:19:49.1205918Z at freshServeStaticFiles (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:5835:35) 2025-10-16T13:19:49.1205942Z at Context.fn (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4403:34) 2025-10-16T13:19:49.1205965Z at segmentMiddleware (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4588:26) 2025-10-16T13:19:49.1205988Z at fn (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4403:34) 2025-10-16T13:19:49.120601Z at file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:4419:20 2025-10-16T13:19:49.1206647Z at NoopContextManager.with (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:981:15) 2025-10-16T13:19:49.1206683Z at ContextAPI.with (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:1048:42) 2025-10-16T13:19:49.120674Z at NoopTracer.startActiveSpan (file:///tmp/deno-compile-server/_fresh/server/server-entry.mjs:1328:27) { 2025-10-16T13:19:49.120676Z name: "NotFound", 2025-10-16T13:19:49.1206778Z code: "ENOENT" 2025-10-16T13:19:49.1206796Z } // { // "id": "MXhUaBIBQkePiTHfY-3y3hrn5C7OZ1RAjFmyNHAKbQA", // "deletedDateTime": null, // "appRoleId": "d4ce6e5d-4a93-43ae-b2f4-230e76248917", // "createdDateTime": "2025-10-20T19:17:23.9036855Z", // "principalDisplayName": "Nathan Live Anderson", // "principalId": "68547831-0112-4742-8f89-31df63edf2de", // "principalType": "User", // "resourceDisplayName": "cyberhybridhub", // "resourceId": "c7f12958-4ee8-4a07-acb8-bf4ac2dcac2b" // } Request headers: { accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,_/_;q=0.8,application/signed-exchange;v=b3;q=0.7", "accept-encoding": "gzip, deflate, br, zstd", "accept-language": "en-US,en;q=0.9", "cache-control": "max-age=0", connection: "keep-alive", cookie: "xx-state-id=353bd790-b53e-4a67-89a1-cad4886c9e57", host: "127.0.0.1:8080", referer: "http://127.0.0.1:8080/", "sec-ch-ua": '"Microsoft Edge";v="141", "Not?A_Brand";v="8", "Chromium";v="141"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"Linux"', "sec-fetch-dest": "document", "sec-fetch-mode": "navigate", "sec-fetch-site": "same-origin", "upgrade-insecure-requests": "1", "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0" } Request cookies: { "xx-state-id": "353bd790-b53e-4a67-89a1-cad4886c9e57" }