integratedhub/README.md
2026-01-20 09:02:26 -06:00

322 lines
14 KiB
Markdown
Executable File

# 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`.
## 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 `window.__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 <your-app>.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" }