test: покрыть файловое хранилище и описать библиотеку

This commit is contained in:
Георгий
2026-07-12 21:07:51 +03:00
parent 0ff0905a9c
commit d3be367910
2 changed files with 232 additions and 1 deletions

186
README.md
View File

@@ -14,9 +14,89 @@ The library intentionally does not know anything about snapshots, route
progress, geolocation, frontend state, or media playback rules. It only parses,
validates, stores, logs, and returns BVK content state.
## Install
```bash
go get gitea.unprism.ru/KRBL/mila
```
## Scope
Mila is a protocol library. It should be embedded into an application service,
for example `wn-content`, and exposed on the address required by the transport
integration.
Mila does:
- parse `GET /set-content`
- parse `GET /get-content`
- validate `route`, `str`, and `tpl_name`
- URL-decode query parameters through Go's standard HTTP parser
- store the latest state in memory or in a JSON file
- return protocol-compatible JSON
- log each HTTP request with method, path, status, remote address, and duration
- call an optional callback after successful `set-content`
Mila does not:
- calculate route progress
- work with geolocation or NMEA
- map `tpl_name` to real media playlists
- read or write snapshots
- communicate with frontend directly
- decide how content should be rendered
## Protocol
The media complex acts as an HTTP server. BVK acts as an HTTP client.
Default address from the PDF:
```text
172.16.16.2:13280
```
Endpoints:
```text
GET /set-content?route=<R>&str=<S>&tpl_name=<T>
GET /get-content
```
`set-content` accepts URL-encoded query parameters:
| Parameter | Required | Meaning |
| --- | --- | --- |
| `route` | yes | route number, default limit is 1-3 characters |
| `str` | no | ticker/running text, default limit is 200 characters |
| `tpl_name` | yes | media content template name, default limit is 200 characters |
`get-content` response:
```json
{
"route": "3",
"str": "Гостиный двор - Gostiny dvor",
"tpl_name": "Гостиный двор"
}
```
`updated_at` is stored internally but is not exposed by `/get-content`, because
the protocol response should stay strict.
## Usage
```go
package main
import (
"log"
"net/http"
"gitea.unprism.ru/KRBL/mila"
)
func main() {
store := mila.NewFileStore("/srv/persistence/client_logs/bvk_content.json")
handler := mila.NewHandler(mila.DefaultConfig(), store,
@@ -29,9 +109,68 @@ srv := &http.Server{
Addr: "0.0.0.0:13280",
Handler: handler,
}
log.Fatal(srv.ListenAndServe())
}
```
## State
## Configuration
Default validation config:
```go
cfg := mila.DefaultConfig()
```
Which currently means:
```go
mila.Config{
MaxRouteLen: 3,
MaxTextLen: 200,
MaxTemplateLen: 200,
}
```
The text/template limits should be confirmed with the integrator. The provided
PDF has an ambiguous text layer for those values.
## Stores
Use `MemoryStore` when state does not need to survive process restart:
```go
store := mila.NewMemoryStore()
```
Use `FileStore` on a device when the latest BVK state should be persisted:
```go
store := mila.NewFileStore("/srv/persistence/client_logs/bvk_content.json")
```
`FileStore` writes atomically through a temporary file and keeps an in-memory
copy after the first successful read or write.
## Callback
`WithOnSet` lets the host application react to a valid BVK update:
```go
handler := mila.NewHandler(mila.DefaultConfig(), store,
mila.WithOnSet(func(state mila.ContentState) {
// Example host-side decisions:
// - publish route and ticker to frontend state
// - map state.Template to a local playlist/template
// - write application-specific logs
}),
)
```
The callback is intentionally synchronous. Keep it fast; if integration work is
heavy, push the state into an internal queue.
## State Model
```json
{
@@ -41,3 +180,48 @@ srv := &http.Server{
"updated_at": "2026-07-12T12:00:00Z"
}
```
Go type:
```go
type ContentState struct {
Route string `json:"route"`
Text string `json:"str"`
Template string `json:"tpl_name"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
}
```
## Status Codes
| Code | When |
| ---: | --- |
| 200 | valid `set-content` or ready `get-content` |
| 400 | invalid request parameters |
| 404 | unknown path |
| 405 | method is not `GET` |
| 500 | store/internal error |
| 503 | `get-content` before first state, canceled/deadline context, unavailable dependency |
Error response:
```json
{
"error": "route: must be at most 3 characters"
}
```
## Testing
```bash
go test ./...
```
Current tests cover:
- successful `set-content` + `get-content`
- `get-content` before state is ready
- invalid route validation
- UTF-8 text/template validation
- file store persistence
- missing file store state