Add distributed F# monitoring platform
Some checks failed
CI / build-test (push) Has been cancelled
CI / containers (push) Has been cancelled

This commit is contained in:
Codex
2026-08-09 18:22:24 +03:00
parent cf8c51e3e8
commit 8ec7ee2ec9
27 changed files with 647 additions and 84 deletions

110
README.md
View File

@@ -1,100 +1,42 @@
# vinext-starter
# IpCheck
A clean full-stack starter running on
[vinext](https://github.com/cloudflare/vinext), with optional Cloudflare D1 and
Drizzle support.
Распределённая система мониторинга IP-адресов на F#. Каждый агент представляет отдельную локацию, синхронизирует общий список IP с центральным сервером, выполняет Ping и TCP-проверки SSH/RDP и отправляет результаты обратно.
## Prerequisites
## Состав первого среза
- Node.js `>=22.13.0`
- F# ASP.NET Core API;
- F# Worker Service для агентов локаций;
- общие контракты и доменная модель;
- схема PostgreSQL;
- Docker-образы сервера и агента;
- Docker Compose для локального окружения;
- CI для сборки, тестов и публикации контейнеров;
- существующий интерфейс в `app/` сохранён как визуальный прототип до переноса на Fable.
## Quick Start
## Локальная проверка
```bash
npm install
npm run dev
npm run build
dotnet restore IpCheck.slnx
dotnet build IpCheck.slnx -c Release
dotnet run --project tests/IpCheck.UnitTests/IpCheck.UnitTests.fsproj -c Release
```
This starter does not use `wrangler.jsonc`.
Запуск сервера:
## Included Shape
- edit site code under `app/`
- `.openai/hosting.json` declares optional Sites D1 and R2 bindings
- `vite.config.ts` simulates declared bindings for local development
- `db/schema.ts` starts intentionally empty
- `examples/d1/` contains an optional D1 example surface
- `drizzle.config.ts` supports local migration generation when needed
## Workspace Auth Headers
Signed-in visitors receive both `oai-authenticated-user-id` and `oai-authenticated-user-email`. Private Sites require every visitor to sign in; public Sites may also have anonymous visitors, for whom neither header is present.
The user ID is stable for the same user on the same Site and different across Sites. Email and name are intended for display or contact purposes.
SIWC-authenticated workspace sites may also receive
`oai-authenticated-user-full-name` when the user's SIWC profile has a non-empty
`name` claim. The full-name value is percent-encoded UTF-8 and is accompanied by
`oai-authenticated-user-full-name-encoding: percent-encoded-utf-8`.
Treat the full name as optional and fall back to email when it is absent:
```tsx
import { headers } from "next/headers";
export default async function Home() {
const requestHeaders = await headers();
const userId = requestHeaders.get("oai-authenticated-user-id");
const email = requestHeaders.get("oai-authenticated-user-email");
const encodedFullName = requestHeaders.get("oai-authenticated-user-full-name");
const fullName =
encodedFullName &&
requestHeaders.get("oai-authenticated-user-full-name-encoding") ===
"percent-encoded-utf-8"
? decodeURIComponent(encodedFullName)
: null;
const displayName = fullName ?? email;
// ...
}
```bash
dotnet run --project src/IpCheck.Server/IpCheck.Server.fsproj
```
## Optional Dispatch-Owned ChatGPT Sign-In
API будет доступен по адресу, указанному ASP.NET Core в консоли. Проверка состояния: `GET /healthz`.
Import the ready-to-use helpers from `app/chatgpt-auth.ts` when the site needs
optional or required ChatGPT sign-in:
## Docker Compose
- Use `getChatGPTUser()` for optional signed-in UI.
- Use `requireChatGPTUser(returnTo)` for server-rendered pages that should send
anonymous visitors through Sign in with ChatGPT.
- Use `chatGPTSignInPath(returnTo)` and `chatGPTSignOutPath(returnTo)` for
browser links or actions.
- Pass a same-origin relative `returnTo` path for the destination after sign-in
or sign-out. The helper validates and safely encodes it.
- Mark protected pages with `export const dynamic = "force-dynamic"` because
they depend on per-request identity headers.
Скопируйте `deploy/.env.example` в `deploy/.env`, замените пароль и запустите:
Dispatch owns `/signin-with-chatgpt`, `/signout-with-chatgpt`, `/callback`, the
OAuth cookies, and identity header injection. Do not implement app routes for
those reserved paths. Routes that do not import and call the helper remain
anonymous-compatible.
```bash
docker compose --env-file deploy/.env -f deploy/docker-compose.yml up -d --build
```
SIWC establishes identity only; it does not prove workspace membership. Use the
Sites hosting platform's access policy controls for workspace-wide restrictions,
or enforce explicit server-side membership or allowlist checks.
## Следующий этап
Use SIWC for account pages, user-specific dashboards, saved records, and write
actions tied to the current ChatGPT user. Leave public content anonymous.
## Useful Commands
- `npm run dev`: start local development
- `npm run build`: verify the vinext build output
- `npm test`: build the starter and verify its rendered loading skeleton
- `npm run db:generate`: generate Drizzle migrations after schema changes
## Learn More
- [vinext Documentation](https://github.com/cloudflare/vinext)
- [Drizzle D1 Guide](https://orm.drizzle.team/docs/get-started/d1-new)
Перевести репозитории IP, локаций и результатов с временного in-memory хранилища на PostgreSQL, добавить регистрацию агентов по одноразовому токену и начать Fable-админку.