Обновлено состояние разработки WSChat и правило ведения .sw

Этот коммит содержится в:
Виктор
2026-05-08 18:38:37 +09:00
родитель 4b46aabc82
Коммит bb09e3b012
+265 -522
Просмотреть файл
@@ -1,11 +1,19 @@
# Development state snapshot # WSChat development state snapshot
Project: WSChat Project: WSChat
Repository: https://github.com/viktor138irk/chat Repository: https://github.com/viktor138irk/chat
Owner: viktor138irk Owner: viktor138irk
Default branch: main Default branch: main
This file is a compact project memory for continuing development in a new chat/dialog. This file is the main project memory for continuing development in a new chat/dialog. Always open this file first before continuing work.
## Mandatory working rule
After every meaningful code, deployment, architecture, or debugging change, update this `.sw` file in the repository.
The user explicitly requested: keep writing/updating `.sw` constantly during further development.
Do not rely on chat history only. `.sw` must remain the source of truth for project state, current bugs, fixes, deployment commands, and next steps.
## Product idea ## Product idea
@@ -13,14 +21,16 @@ Build a self-hosted live chat system similar to Jivo, but with Telegram as the o
Website visitors use an embeddable widget. Messages go to selected Telegram operators. Operators reply in Telegram, and replies return to the website widget. Website visitors use an embeddable widget. Messages go to selected Telegram operators. Operators reply in Telegram, and replies return to the website widget.
Future direction: Android app support should be planned in the API, but MVP is VPS + website widget + Telegram operators.
## Current production/test deployment ## Current production/test deployment
Current tested domains: Current tested domains:
```text ```text
https://widget.stackworks.ru/ -> widget works https://widget.stackworks.ru/ -> widget static site
https://widget.stackworks.ru/admin/ -> admin works after Vite base fix https://widget.stackworks.ru/admin/ -> admin panel
https://api.stackworks.ru/health -> backend API works https://api.stackworks.ru/health -> backend API through FastPanel reverse proxy
``` ```
Current VPS paths: Current VPS paths:
@@ -39,13 +49,54 @@ Current PM2 process:
wschat-backend wschat-backend
``` ```
Current local backend: Backend listens locally only:
```text ```text
http://127.0.0.1:3000 http://127.0.0.1:3000
``` ```
Current backend env requirements: FastPanel reverse proxy:
```text
api.stackworks.ru -> http://127.0.0.1:3000
```
Widget/admin webroot:
```text
/var/www/widget_stack_usr/data/www/widget.stackworks.ru
```
Admin panel lives under:
```text
/var/www/widget_stack_usr/data/www/widget.stackworks.ru/admin/
```
## Architecture decision
MVP is VPS-only.
Raspberry Pi 3B was removed from MVP because of Node.js/OS/DPKG problems:
- 32-bit OS: NodeSource armhf incompatibility and segfaults.
- 64-bit OS: NodeSource arm64 produced `Illegal instruction`.
- APT/DPKG corruption was observed.
Current architecture:
```text
Website with embed widget
-> widget.stackworks.ru static widget/admin
-> api.stackworks.ru HTTPS reverse proxy
-> Node.js Fastify backend on 127.0.0.1:3000
-> SQLite at /opt/ws-chat/data/chat.sqlite
-> Telegram bridge via Telegraf
-> optional SOCKS5 proxy for Telegram
-> Telegram operators
```
## Current backend env requirements
```env ```env
APP_ENV=production APP_ENV=production
@@ -58,28 +109,27 @@ DATABASE_PATH=/opt/ws-chat/data/chat.sqlite
ADMIN_ORIGIN=https://widget.stackworks.ru ADMIN_ORIGIN=https://widget.stackworks.ru
WIDGET_ORIGIN=https://widget.stackworks.ru WIDGET_ORIGIN=https://widget.stackworks.ru
ADMIN_BASE_PATH=/admin ADMIN_BASE_PATH=/admin
TELEGRAM_BOT_TOKEN=
TELEGRAM_PROXY_ENABLED=false
TELEGRAM_PROXY_TYPE=socks5
TELEGRAM_PROXY_HOST=127.0.0.1
TELEGRAM_PROXY_PORT=9050
TELEGRAM_PROXY_USERNAME=
TELEGRAM_PROXY_PASSWORD=
``` ```
Important fixes already made: Important: Telegram settings are now also persisted in SQLite `settings` table and managed from admin panel.
- Admin panel previously displayed `API: http://localhost:3000` and `Failed to fetch` because browser localhost points to the user's PC, not VPS. ## Database
- `admin-panel/src/main.jsx` fallback API URL was changed to `https://api.stackworks.ru` in commit `3e956e5c2ab65fe563f6c5d71bb2d032cbf8bcad`.
- Backend did not reliably load `backend/.env`, so env stayed `development` and CORS did not include `access-control-allow-origin` for `https://widget.stackworks.ru`.
- `backend/src/config.js` now loads `backend/.env` by absolute path in commit `4f6339b37c0bbdfa11c12cacb5d12265fb5dd59b`.
- Admin HTML title was changed from `Raspi Chat Admin` to `WSChat Admin` in commit `e5cac5ef34287931f7661bc26dcf739cdf9e7f90`.
- If Telegram bot token was ever pasted into chat/logs, it must be revoked/regenerated in BotFather before production use.
## Current backend persistence implementation SQLite DB path:
SQLite layer added in commit `502d214eac515863037d8f2bc6f09161dc19624e`.
New file:
```text ```text
backend/src/db.js /opt/ws-chat/data/chat.sqlite
``` ```
It creates and manages: Tables currently managed by `backend/src/db.js`:
```text ```text
sites sites
@@ -91,597 +141,290 @@ messages
settings settings
``` ```
SQLite database path comes from: Default site:
```env
DATABASE_PATH=/opt/ws-chat/data/chat.sqlite
```
Backend now calls `migrate()` on startup and creates default site:
```text ```text
site id: site_default site id: site_default
widget_key: site_default widget_key: site_default
``` ```
Widget message persistence added in commit `bb6dcb106948f83ec588b03777c3ce263509e80a`. Important Telegram settings keys:
Current backend endpoints: ```text
telegram.bot_token
telegram.proxy.enabled
telegram.proxy.type
telegram.proxy.host
telegram.proxy.port
telegram.proxy.username
telegram.proxy.password
```
Check saved proxy settings on VPS:
```bash
sqlite3 /opt/ws-chat/data/chat.sqlite "select key, value from settings where key like 'telegram.proxy.%';"
```
Check token length without exposing token:
```bash
sqlite3 /opt/ws-chat/data/chat.sqlite "select key, length(value) as len from settings where key='telegram.bot_token';"
```
## Current backend endpoints
```text ```text
GET /health GET /health
GET /api/config/public GET /api/config/public
GET /api/admin/stats GET /api/admin/stats
GET /api/admin/messages?limit=50 GET /api/admin/messages?limit=50
GET /api/admin/telegram/settings
POST /api/admin/telegram/settings
POST /api/admin/telegram/test-proxy
POST /api/admin/telegram/restart
POST /api/widget/message POST /api/widget/message
GET /ws GET /ws
``` ```
`POST /api/widget/message` now: `/health` now should include Telegram bridge state:
- validates `siteId`, `visitorId`, `message`;
- checks active site by `widget_key`;
- creates/touches visitor;
- creates/reuses open conversation;
- saves visitor message into SQLite;
- returns `status: saved`, `conversationId`, and `messageId`.
Test commands after pulling latest code on VPS:
```bash
cd /opt/ws-chat/source
git pull --ff-only origin main
npm install
pm2 restart wschat-backend --update-env
curl http://127.0.0.1:3000/health
curl -s https://api.stackworks.ru/api/admin/stats | jq
curl -s -X POST https://api.stackworks.ru/api/widget/message \
-H 'Content-Type: application/json' \
-H 'Origin: https://widget.stackworks.ru' \
-d '{"siteId":"site_default","visitorId":"test_visitor_1","message":"Тестовое сообщение WSChat"}' | jq
curl -s https://api.stackworks.ru/api/admin/messages | jq
```
Expected POST result:
```json ```json
{ {
"ok": true, "ok": true,
"status": "saved", "service": "wschat-backend",
"conversationId": "conv_...", "env": "production",
"messageId": "msg_..." "telegram": {
"enabled": true,
"running": true,
"error": "",
"username": "...",
"proxyEnabled": true,
"startedAt": "...",
"hasBot": true
}
} }
``` ```
## Current architecture ## Admin panel current state
The architecture is VPS-only. Admin is a React/Vite panel at:
```text ```text
Website with embedded widget https://widget.stackworks.ru/admin/
-> widget.stackworks.ru static widget and admin panel on VPS/FastPanel
-> api.stackworks.ru public HTTPS endpoint on VPS/FastPanel
-> local reverse proxy to Node.js backend on VPS
-> SQLite on VPS
-> Telegram bot API / optional SOCKS5
-> Telegram operators
Admin user
-> widget.stackworks.ru/admin/ static admin panel on VPS/FastPanel
-> api.stackworks.ru backend on same VPS
``` ```
## Architecture decision update Implemented:
The architecture was changed from Raspberry Pi backend to VPS-only deployment. - dark compact dashboard UI;
- API health indicator;
- stats cards;
- recent messages list from SQLite;
- auto-refresh of dashboard data;
- Telegram/SOCKS5 settings form;
- dirty-state protection so auto-refresh no longer wipes input while typing;
- token/password masks `********`;
- SOCKS5 enable/host/port/login/password fields;
- save settings button;
- test proxy button;
- reset form button.
Reason: Important fix: dashboard auto-refresh must not reload Telegram/SOCKS5 form while the user is editing it.
- Raspberry Pi 3B caused repeated low-level system issues. ## Telegram bridge current state
- 32-bit OS had NodeSource `armhf` incompatibility.
- 64-bit OS with NodeSource arm64 produced `Illegal instruction` on Node.js.
- APT/DPKG then showed corrupted archives and `/var/lib/dpkg/diversions` issues.
- Continuing on Raspberry Pi would waste time and increase operational risk.
New decision: Runtime bridge file:
```text ```text
VPS with FastPanel runs everything: backend/src/telegram.js
- backend API
- WebSocket
- Telegram bot
- SQLite database initially
- widget static files
- admin panel static files under /admin/
``` ```
Raspberry Pi is removed from MVP architecture. It can be revisited later as an optional edge node, but not for the first production version. Dependencies:
## Deployment decisions
- Project name: WSChat.
- Main project directory: `/opt/ws-chat`.
- Cloudflare must not be used because of availability issues in Russia.
- Everything runs on VPS with FastPanel.
- FastPanel must manage domains, SSL, and web server configs manually.
- Project scripts must not create domains or edit global FastPanel configs.
- Backend runs locally on VPS, bound to `127.0.0.1:3000`.
- `api.stackworks.ru` is a reverse proxy to `http://127.0.0.1:3000`.
- `widget.stackworks.ru` serves embeddable widget static files.
- Admin panel is served from the same webroot under `https://widget.stackworks.ru/admin/`.
- SQLite database initially lives on VPS under project data directory.
- PostgreSQL can be introduced later if needed.
- WireGuard is no longer required for MVP.
- No Raspberry home networking or port forwarding is required.
## VPS/FastPanel target
VPS with FastPanel manually configured by the user.
Required FastPanel sites:
```text ```text
widget.stackworks.ru -> static widget + /admin/ admin panel telegraf
api.stackworks.ru -> reverse proxy to local backend on VPS socks-proxy-agent
node-fetch
``` ```
FastPanel webroot for widget/admin is expected to look like: Current behavior:
- backend starts Telegram bridge on startup using settings from SQLite;
- `/start` registers Telegram user as active operator;
- new operator is linked to `site_default` through `site_operators`;
- `/status` replies with bridge status;
- text reply in Telegram can be saved as operator message if it is a reply to WSChat notification containing `Conversation: conv_...`;
- website visitor message is saved to SQLite and then sent to active Telegram operators;
- operator reply is saved to SQLite, but delivery back to widget via WebSocket is not finished yet.
Important: bridge originally used `socks5://`, but successful curl test showed Telegram must be accessed via `socks5h://` so DNS resolves through proxy.
Current fix:
```text ```text
/var/www/<fastpanel-user>/data/www/widget.stackworks.ru backend/src/telegram.js uses socks5h:// for SocksProxyAgent
``` ```
In the current install, the correct widget webroot should be: Commit for this fix:
```text ```text
/var/www/widget_stack_usr/data/www/widget.stackworks.ru 4b46aabc8210158f97c3c6e9274b8f703f7a8aa2
``` ```
Do not publish widget/admin files into the `api.stackworks.ru` webroot. ## Telegram/SOCKS5 debugging history
The backend source and runtime should live outside public webroots: Observed `/health` error before socks5h fix:
```text ```text
/opt/ws-chat/source request to https://api.telegram.org/bot.../getMe failed, reason: Proxy connection timed out
/opt/ws-chat/data
/opt/ws-chat/logs
/opt/ws-chat/backups
/opt/ws-chat/updates
``` ```
`api.stackworks.ru` may have a webroot created by FastPanel, but project files must not be published there. It should proxy to: User confirmed SOCKS5 itself works from VPS with curl:
```bash
curl -v --proxy 'socks5h://proxy:Adelina%402015@194.156.65.175:42673' https://api.telegram.org
```
Result showed:
```text ```text
http://127.0.0.1:3000 SOCKS5 request granted
HTTP/2 302
``` ```
## Ports This proves proxy works and Telegram is reachable through it.
VPS public ports: Important note: the SOCKS5 password contains `@`. In curl URL it must be encoded as `%40`, but in admin panel it should be entered normally as `Adelina@2015`. Code uses `encodeURIComponent`, so the app should encode it correctly.
- 80/tcp for HTTP/Let's Encrypt Current proxy values used in testing:
- 443/tcp for HTTPS widget/admin/API
- SSH port, usually 22/tcp or custom
Backend port:
- Node.js backend listens on `127.0.0.1:3000` only.
- Do not expose port 3000 publicly.
No WireGuard port is required for MVP.
## SOCKS5 requirement
Telegram settings must support optional SOCKS5 proxy:
```env
TELEGRAM_PROXY_ENABLED=false
TELEGRAM_PROXY_TYPE=socks5
TELEGRAM_PROXY_HOST=127.0.0.1
TELEGRAM_PROXY_PORT=9050
TELEGRAM_PROXY_USERNAME=
TELEGRAM_PROXY_PASSWORD=
```
Admin panel should eventually expose:
- enable/disable SOCKS5
- host
- port
- username
- password
- test connection button
## Frontend and backend update decision
The user wants manual-safe installation on VPS first, to avoid breaking FastPanel.
Future update mechanism:
- Assistant can prepare an update bundle file.
- User uploads it to VPS.
- Auto-updater applies changes safely.
- Updates can cover admin, widget, backend/API, docs, and config templates.
Recommended project directory on VPS:
```text ```text
/opt/ws-chat/ Host: 194.156.65.175
source/ Port: 42673
updates/ Login: proxy
backups/ Password: Adelina@2015
logs/ SOCKS5 enabled: true
build/
data/
``` ```
FastPanel owns public directory: Do not expose Telegram bot token in chat or logs.
```text ## Important commits after original snapshot
/var/www/<fastpanel-user>/data/www/widget.stackworks.ru
- `eae37d38a98026c39e4cd71e0f54f94d4785d9e9` — admin dashboard shows stats/messages.
- `b9b68d401ce0a6661f169064a1fee4e5ca441f19` — updated admin styling.
- `d601e6925718e5d8c59394682da05ff25e4581a0` — DB functions for Telegram/SOCKS5 settings.
- `966c3cf531c61d13c300bb584b3cb50453c56a7c` — backend API for Telegram/SOCKS5 settings.
- `c1169032ee0809fcc0f52f8e7d1b8cdfd4c1f375` — proxy config validation endpoint.
- `1c644e1df7ebd5fb88e92fb3f6360f86355aac04` — Telegram/SOCKS5 form in admin.
- `53fad336d3013b9f1fc1e25fdac4149956dc356b` — styles for Telegram/SOCKS5 form.
- `9999139ab5c1cf227187d6b596caea8e2c0e7f32` — fixed auto-refresh wiping SOCKS5 form.
- `760e85e342fd1c08e9a80de6eb6429fca17ec3ac` — added backend dependencies for Telegram/SOCKS5 bridge.
- `5c6da6582e9d7077c4d7fe504b9731f853058072` — operators and operator messages DB functions.
- `72edf824e0d7ebf92dfc27dfc8a956d2d927448c` — added runtime Telegram bridge file.
- `47096dd0de601448a2c7f9ba1d5ac724f3bd7b69` — connected Telegram bridge to backend runtime.
- `b22381061236a3a9568a5a906375f73dcbe16f87` — restartable Telegram bridge.
- `27e94c96533b2955325d1d7e407f53d98bd0e81b` — restart endpoint and attempted auto-restart after settings save.
- `8632c577a8b798bd7c5480998156919988affccb` — separated settings save from bridge restart to avoid timeout wiping UI state.
- `4b46aabc8210158f97c3c6e9274b8f703f7a8aa2` — changed Telegram SOCKS agent to `socks5h://`.
## Deployment/update commands
Backend update:
```bash
cd /opt/ws-chat/source
git pull --ff-only origin main
cd backend
npm install
pm2 restart wschat-backend --update-env
``` ```
Backend should be managed by PM2: Hard reset if server is behind or files are missing:
```text ```bash
pm2 process: wschat-backend cd /opt/ws-chat/source
entry: /opt/ws-chat/source/backend/src/server.js git fetch origin main
git reset --hard origin/main
git clean -fd
cd backend
npm install
pm2 delete wschat-backend
pm2 start src/server.js --name wschat-backend --update-env
pm2 save
```
Admin/widget build and publish:
```bash
cd /opt/ws-chat/source
npm install
npm run build
rsync -av --delete widget/dist/ /var/www/widget_stack_usr/data/www/widget.stackworks.ru/
rsync -av --delete admin-panel/dist/ /var/www/widget_stack_usr/data/www/widget.stackworks.ru/admin/
```
Health check:
```bash
curl -s http://127.0.0.1:3000/health | jq
```
Logs:
```bash
pm2 logs wschat-backend --lines 100
``` ```
## FastPanel safety rules ## FastPanel safety rules
Never from project scripts: Never from project scripts:
- edit `/etc/nginx/nginx.conf` - edit `/etc/nginx/nginx.conf`;
- overwrite FastPanel vhost configs - overwrite FastPanel vhost configs;
- run broad `systemctl restart nginx` - run broad `systemctl restart nginx`;
- install packages that replace FastPanel web stack - install packages that replace FastPanel web stack;
- run frontend/backend as root beyond the current root-based MVP install model - bind project services directly to ports 80/443;
- bind project services directly to ports 80/443 - delete parent `/var/www` directories;
- delete parent `/var/www` directories - run `rsync --delete` against `/var/www` or parent directories.
Static deployment should copy files only into exact domain webroot directories. Only copy static files into exact domain webroot directories.
Use rsync carefully: ## Current next steps
```bash 1. Pull latest code with `socks5h://` fix on VPS.
rsync -av --delete widget/dist/ /var/www/widget_stack_usr/data/www/widget.stackworks.ru/ 2. Restart backend with PM2.
rsync -av --delete admin-panel/dist/ /var/www/widget_stack_usr/data/www/widget.stackworks.ru/admin/ 3. Check `/health` and confirm `telegram.running: true`.
``` 4. In Telegram, send `/start` to the bot and confirm operator registration.
5. Send a message from widget and confirm it arrives to Telegram operator.
Never run `rsync --delete` against `/var/www` or parent folders. 6. Implement delivery of Telegram operator replies back to widget through WebSocket.
7. Add admin UI bridge status/restart button.
## Old Raspberry Pi attempt archive 8. Add admin list of Telegram operators.
Raspberry Pi was originally planned as backend host but was removed from MVP.
Issues encountered:
- Raspberry Pi 3B with 32-bit OS: NodeSource does not support `armhf`.
- Raspberry Pi 3B with 32-bit OS: `node -v` and `npm -v` returned `Segmentation fault` after attempted setup.
- 32-bit install also showed dpkg metadata corruption.
- Raspberry Pi 3B with 64-bit OS: NodeSource arm64 installed but `node -v` and `npm -v` returned `Illegal instruction`.
- Later apt/dpkg showed corrupted `.deb` archives and corrupted `/var/lib/dpkg/diversions`.
Conclusion:
```text
Do not use Raspberry Pi 3B for MVP backend.
Use VPS-only deployment.
```
## Current repository structure
```text
.
├── .gitignore
├── .sw
├── README.md
├── package.json
├── backend/
│ ├── .env.example
│ ├── package.json
│ └── src/
│ ├── config.js
│ ├── db.js
│ └── server.js
├── admin-panel/
│ ├── index.html
│ ├── package.json
│ ├── vite.config.js
│ └── src/
│ ├── main.jsx
│ └── styles.css
├── widget/
│ ├── index.html
│ ├── package.json
│ └── src/
│ └── widget.js
├── deploy/
│ ├── deploy-agent/
│ └── vps/
│ ├── .env.example
│ ├── bootstrap.sh
│ └── install.sh
└── docs/
├── FASTPANEL.md
├── FASTPANEL_MANUAL_FRONTEND.md
├── INSTALL.md
├── RASPBERRY_PI.md
├── UPDATE_BUNDLE.md
└── VPS_ONLY_INSTALL.md
```
## Implemented so far
### VPS interactive installer
Added `deploy/vps/install.sh`.
It is an interactive root installer with progress and error logging.
Features:
- shows current step `[01/13]` style;
- writes log file to `/tmp/wschat-install-YYYYMMDD-HHMMSS.log`;
- saves primary settings to `/opt/ws-chat/install-state.env`;
- on repeated runs, can reuse saved settings;
- supports `--yes` to use saved settings without questions;
- supports `--reset` to ask settings again;
- asks for project path, widget/admin domain, API domain, FastPanel widget webroot, Telegram token, JWT secret;
- validates FastPanel webroot path shape;
- installs base packages;
- installs Node.js 20 via NodeSource;
- installs PM2;
- creates `/opt/ws-chat` directories;
- clones/updates repo;
- installs npm dependencies;
- writes `backend/.env`;
- writes `/opt/ws-chat/install-state.env`;
- starts/restarts PM2 process `wschat-backend`;
- checks backend health at `http://127.0.0.1:3000/health`;
- builds admin and widget;
- publishes widget files into widget webroot and admin files into `/admin/`;
- prints FastPanel reverse proxy instructions for `api.stackworks.ru`.
Installer does not create domains or edit FastPanel configs.
Run on VPS as root:
```bash
cd /opt/ws-chat/source
bash deploy/vps/install.sh
```
Use saved settings without questions:
```bash
cd /opt/ws-chat/source
bash deploy/vps/install.sh --yes
```
Reset settings:
```bash
cd /opt/ws-chat/source
bash deploy/vps/install.sh --reset
```
### Root workspace
- npm workspaces configured.
- Root package renamed from `raspi-telegram-live-chat` to `wschat`.
- Workspace package names renamed to `@wschat/*`.
- Root scripts:
- `dev:backend`
- `dev:admin`
- `build:admin`
- `build:widget`
- `build`
- `deploy:frontend`
### Backend
Stack:
- Node.js
- Fastify
- @fastify/cors
- @fastify/rate-limit
- @fastify/websocket
- better-sqlite3
- SQLite
- nanoid
- telegraf dependency already added but Telegram bridge not implemented yet
Current endpoints:
```text
GET /health
GET /api/config/public
GET /api/admin/stats
GET /api/admin/messages?limit=50
POST /api/widget/message
GET /ws
```
For VPS-only architecture, backend env should use:
```env
APP_ENV=production
APP_HOST=127.0.0.1
APP_PORT=3000
PUBLIC_API_URL=https://api.stackworks.ru
PUBLIC_WS_URL=wss://api.stackworks.ru/ws
DATABASE_PATH=/opt/ws-chat/data/chat.sqlite
ADMIN_ORIGIN=https://widget.stackworks.ru
WIDGET_ORIGIN=https://widget.stackworks.ru
ADMIN_BASE_PATH=/admin
```
Backend health service name was renamed from `raspi-chat-backend` to `wschat-backend` in commit `ac14400b2eec875231f6300b7a48e8940cf73996`.
### Admin panel
React/Vite shell exists.
It shows:
- project dashboard;
- API health check;
- FastPanel-safe deployment note;
- SOCKS5 note.
Admin panel is served under:
```text
https://widget.stackworks.ru/admin/
```
Added `admin-panel/vite.config.js` with:
```js
base: '/admin/'
```
This fixed the white page caused by assets loading from `/assets/...` instead of `/admin/assets/...`.
Admin API fallback was fixed from `http://localhost:3000` to `https://api.stackworks.ru` in commit `3e956e5c2ab65fe563f6c5d71bb2d032cbf8bcad`.
Admin HTML title was changed from `Raspi Chat Admin` to `WSChat Admin` in commit `e5cac5ef34287931f7661bc26dcf739cdf9e7f90`.
### Widget
Vanilla JS widget shell exists.
It:
- creates chat button;
- opens chat panel;
- creates visitorId in localStorage;
- sends messages to backend endpoint.
Current embed example:
```html
<script
src="https://widget.stackworks.ru/widget.js"
data-site-id="site_default"
data-api-url="https://api.stackworks.ru">
</script>
```
Need to ensure production Vite build emits stable `widget.js` file.
### Deploy agent
FastPanel-safe deploy script exists:
```text
deploy/deploy-agent/src/deploy-frontend.js
```
It currently focuses on frontend publishing and needs to be updated for current single-webroot widget/admin deployment:
- git fetch/pull;
- npm ci/install;
- builds admin-panel;
- builds widget;
- validates FastPanel webroot path;
- rsyncs widget dist to widget webroot;
- rsyncs admin dist to widget webroot `/admin/`;
- does not touch FastPanel configs.
Need to extend deployment process for VPS-only backend:
- install backend deps;
- keep `/opt/ws-chat/data` persistent;
- restart PM2 process `wschat-backend`;
- never expose backend on public port.
Important env variable:
```env
FASTPANEL_SAFE_MODE=true
```
## Existing docs
- `docs/VPS_ONLY_INSTALL.md`: current VPS-only install guide, needs final cleanup for widget/admin same-domain scheme.
- `docs/INSTALL.md`: old full install guide for VPS + Raspberry Pi; deprecated.
- `docs/FASTPANEL.md`: FastPanel-safe deployment guide; needs update for backend on same VPS.
- `docs/FASTPANEL_MANUAL_FRONTEND.md`: manual frontend installation through FastPanel.
- `docs/RASPBERRY_PI.md`: now historical/optional, not MVP.
- `docs/UPDATE_BUNDLE.md`: future update bundle workflow; needs update for backend on VPS and `/opt/ws-chat`.
## Important previous commits
- Initial project spec: `aea8a9f49089ffd6b5a8ace365fc4eaa8c4ea154`
- Frontend deployment requirement: `1a914b9e546f6a0d9b60be6f8cf80858b1d25a75`
- FastPanel-safe requirement: `80f0e77e76f6a0b79e875fed5baf2243fbe0a11e`
- Initial project skeleton: multiple commits after that
- Install guide: `4f86690a0118f69243ce4da9b515aaace5b20017`
- Manual FastPanel frontend guide: `ba08112dc628fd276a2f8eade63145b32aa42c95`
- Update bundle workflow: `b1fa5ead43f33e80c7208b98bcea6e0fa68d5682`
- Raspberry armhf bootstrap fix: `fbe84c8b16a51cdd4931ecf0b1e0fa8654edec6a`
- Architecture switched to VPS-only after Raspberry issues: `28b0ca37c4032633811cce4dc096d1c714c5d5a2`
- Backend health renamed to WSChat: `ac14400b2eec875231f6300b7a48e8940cf73996`
- Backend .env absolute loading fix: `4f6339b37c0bbdfa11c12cacb5d12265fb5dd59b`
- Admin Vite base `/admin/` added: `9943376645882eeb3cdc372b5292c72519e005b2`
- Admin API fallback fixed: `3e956e5c2ab65fe563f6c5d71bb2d032cbf8bcad`
- Admin HTML title renamed to WSChat: `e5cac5ef34287931f7661bc26dcf739cdf9e7f90`
- SQLite DB layer added: `502d214eac515863037d8f2bc6f09161dc19624e`
- Widget message persistence added: `bb6dcb106948f83ec588b03777c3ce263509e80a`
## Next development steps
1. Pull latest backend persistence changes on VPS.
2. Restart PM2 and verify SQLite DB creation at `/opt/ws-chat/data/chat.sqlite`.
3. Test POST `/api/widget/message` with `siteId: site_default`.
4. Test GET `/api/admin/messages` and `/api/admin/stats`.
5. Update admin UI to show message/stats cards.
6. Update deploy-agent for widget/admin same webroot and backend restart.
7. Fix widget production build so it outputs stable `widget.js`.
8. Implement Telegram bot bridge:
- send website messages to allowed operators
- map Telegram replies to conversations
- send replies back to widget via WebSocket
9. Add admin auth. 9. Add admin auth.
10. Add admin CRUD: 10. Add site CRUD and operator-site permissions.
- sites 11. Fix production widget build to emit stable `widget.js`.
- operators 12. Add origin/domain validation: `site_id + Origin` must match configured site.
- operator-site permissions 13. Add updater bundle workflow.
- Telegram settings 14. Continue updating this `.sw` after each meaningful change.
- SOCKS5 settings
11. Add origin/domain validation:
- `site_id + Origin` must match configured site.
12. Add manual update section in admin panel.
13. Add update bundle generator and apply script.
14. Prepare Android-ready API later.
## User preferences and constraints ## User preferences and constraints
- User wants practical development, not only planning. - User wants practical development, not only planning.
- User wants all work in GitHub repository `viktor138irk/chat`. - User wants all work in GitHub repository `viktor138irk/chat`.
- User wants to be able to resume development in a new dialog using this `.sw` file. - User wants to resume development in new dialogs using this `.sw` file.
- User explicitly wants `.sw` continuously updated.
- User prefers not to risk breaking FastPanel. - User prefers not to risk breaking FastPanel.
- User wants manual control over domains in FastPanel. - User wants manual control over domains in FastPanel.
- User wants future auto-update file/bundle workflow. - User wants future auto-update file/bundle workflow.
- User changed architecture to VPS-only after Raspberry issues. - User changed architecture to VPS-only after Raspberry issues.
- User named the system WSChat and chose `/opt/ws-chat` as the project path.
- VPS currently uses root user by default, so MVP installation can run as root. - VPS currently uses root user by default, so MVP installation can run as root.
- Widget and admin must live in one FastPanel site: widget at `/`, admin at `/admin/`. - Widget and admin must live in one FastPanel site: widget at `/`, admin at `/admin/`.
## How to continue in a new chat ## How to continue in a new chat
Open this file first. Then continue from "Next development steps". Open `.sw` first, then continue from `Current next steps`.
Recommended next task: Recommended immediate task:
```text ```text
Pull latest changes on VPS, test SQLite message persistence, then show messages/stats in admin UI. Pull latest code on VPS, restart backend, verify Telegram bridge with socks5h proxy, then test /start.
``` ```