[WIP]: Focused implementation plan to complete high-priority TODOs (payments, ACME endpoint, token uniqueness) and deliver key feature integrations (dashboards, calendar, documents, reminders)
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 underroutes/api/*. - Services: business logic in
services/*. WhenE2E_TEST=true, services read/write deterministic fixtures fromservices/e2eFixtures.tsinstead of the database. - Auth in tests: E2E mode accepts a header
x-e2e-userto bypass auth (services/stateMiddleware.ts), and UI tests set a skip-encryption flag viatests/e2e/helpers.ts.
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=trueenables fixture-backed services (services/e2eFixtures.ts). - Auth bypass: use
x-e2e-userheader (values likelandlord,tenant,landlord-onboarding) to map to fixture users. - Deterministic time:
applyDeterministicPage()stubsDate.now()andMath.random()and disables animations. - Encryption bypass:
useE2EUser()setswindow.__E2E_SKIP_ENCRYPTION__and a localStorage flag to keep test data readable. - Web server: Playwright config uses
deno task devwithE2E_TEST=trueand 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()anduseE2EUser()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(...)withe2eHeaders(...)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 fromplaywright.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" }