feat(architecture): add complete technical architecture for SimpleNote
- ARCHITECTURE.md: main architecture document - api-spec.yaml: full OpenAPI 3.0 spec - folder-structure.md: detailed folder layout - data-format.md: JSON schemas for .meta.json, .library.json, .tag-index.json - env-template.md: environment variables documentation - cli-protocol.md: CLI-to-API communication protocol
This commit is contained in:
274
cli-protocol.md
Normal file
274
cli-protocol.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# SimpleNote CLI - Protocolo de Comunicación
|
||||
|
||||
## 1. Overview
|
||||
|
||||
El CLI (`simplenote-cli`) se comunica con el servidor (`simplenote-web`) exclusivamente
|
||||
vía HTTP REST usando el API documentado en `api-spec.yaml`.
|
||||
|
||||
No hay comunicación peer-to-peer ni protocolos binarios. Todo es JSON sobre HTTP.
|
||||
|
||||
```
|
||||
┌──────────────────┐ HTTP/REST ┌─────────────────┐
|
||||
│ simplenote-cli │ ◄──────────────────► │ simplenote-web │
|
||||
│ (Commander.js) │ Bearer token auth │ (Express.js) │
|
||||
└──────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
└──── ~/.config/simplenote/config.json ──┘
|
||||
```
|
||||
|
||||
## 2. Cliente HTTP
|
||||
|
||||
### 2.1 Clase `SimpleNoteClient`
|
||||
|
||||
```javascript
|
||||
// src/api/client.js
|
||||
const axios = require('axios');
|
||||
|
||||
class SimpleNoteClient {
|
||||
constructor({ baseUrl, token }) {
|
||||
this.baseUrl = baseUrl.replace(/\/$/, ''); // strip trailing slash
|
||||
this.token = token;
|
||||
this._axios = axios.create({
|
||||
baseURL: this.baseUrl,
|
||||
timeout: 10000,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
}
|
||||
|
||||
_authHeaders() {
|
||||
return this.token ? { Authorization: `Bearer ${this.token}` } : {};
|
||||
}
|
||||
|
||||
async _request(method, path, data) {
|
||||
try {
|
||||
const res = await this._axios.request({
|
||||
method,
|
||||
url: path,
|
||||
data,
|
||||
headers: this._authHeaders()
|
||||
});
|
||||
return res.data;
|
||||
} catch (err) {
|
||||
if (err.response) {
|
||||
const msg = err.response.data?.error || err.message;
|
||||
throw new Error(`API Error ${err.response.status}: ${msg}`);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// Auth
|
||||
async verifyToken() { return this._request('GET', '/auth/verify'); }
|
||||
|
||||
// Documents
|
||||
async listDocuments(params) {
|
||||
const qs = new URLSearchParams(params).toString();
|
||||
return this._request('GET', `/documents${qs ? '?' + qs : ''}`);
|
||||
}
|
||||
async getDocument(id) { return this._request('GET', `/documents/${id}`); }
|
||||
async createDocument(data) { return this._request('POST', '/documents', data); }
|
||||
async updateDocument(id, data) { return this._request('PUT', `/documents/${id}`, data); }
|
||||
async deleteDocument(id) { return this._request('DELETE', `/documents/${id}`); }
|
||||
async exportDocument(id) { return this._request('GET', `/documents/${id}/export`); }
|
||||
|
||||
// Documents > Tags
|
||||
async addTagsToDocument(id, tags) {
|
||||
return this._request('POST', `/documents/${id}/tags`, { tags });
|
||||
}
|
||||
|
||||
// Libraries
|
||||
async listLibraries() { return this._request('GET', '/libraries'); }
|
||||
async getLibrary(id) { return this._request('GET', `/libraries/${id}`); }
|
||||
async createLibrary(data) { return this._request('POST', '/libraries', data); }
|
||||
async getLibraryTree(id) { return this._request('GET', `/libraries/${id}/tree`); }
|
||||
async listLibraryDocuments(id) {
|
||||
return this._request('GET', `/libraries/${id}/documents`);
|
||||
}
|
||||
|
||||
// Tags
|
||||
async listTags() { return this._request('GET', '/tags'); }
|
||||
async getTagDocuments(tag) { return this._request('GET', `/tags/${tag}`); }
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Flujo de Auth
|
||||
|
||||
### 3.1 Login Inicial
|
||||
|
||||
```bash
|
||||
simplenote auth login snk_a1b2c3d4e5f6...
|
||||
```
|
||||
|
||||
Flujo:
|
||||
1. CLI guarda token en `~/.config/simplenote/config.json`
|
||||
2. CLI llama `GET /api/v1/auth/verify` para validar
|
||||
3. Si 200 → login exitoso. Si 401 → token inválido.
|
||||
|
||||
### 3.2 Requests Subsecuentes
|
||||
|
||||
Todas las requests incluyen:
|
||||
```
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
### 3.3 Verificación de Status
|
||||
|
||||
```bash
|
||||
simplenote auth status
|
||||
```
|
||||
→ `GET /auth/verify` → muestra si token es válido.
|
||||
|
||||
## 4. Comandos CLI Detallados
|
||||
|
||||
### 4.1 Documents
|
||||
|
||||
```bash
|
||||
# Listar con filtros
|
||||
simplenote doc list --tag backend --library 550e8400... --type requirement
|
||||
simplenote doc list --tag api --limit 10
|
||||
|
||||
# Ver documento
|
||||
simplenote doc get 770e8400-e29b-41d4-a716-446655440002
|
||||
|
||||
# Crear
|
||||
simplenote doc create \
|
||||
--title "API Authentication" \
|
||||
--content "# API Authentication\n\n..." \
|
||||
--tags "backend,api,auth" \
|
||||
--type requirement \
|
||||
--priority high \
|
||||
--library 550e8400-e29b-41d4-a716-446655440000
|
||||
|
||||
# Actualizar
|
||||
simplenote doc update 770e8400... --title "Nuevo título" --content "..."
|
||||
simplenote doc update 770e8400... --status approved
|
||||
|
||||
# Eliminar
|
||||
simplenote doc delete 770e8400...
|
||||
|
||||
# Exportar como markdown
|
||||
simplenote doc export 770e8400...
|
||||
|
||||
# Agregar tags
|
||||
simplenote doc add-tags 770e8400... --tags "new-tag,another"
|
||||
```
|
||||
|
||||
### 4.2 Libraries
|
||||
|
||||
```bash
|
||||
# Listar librerías raíz
|
||||
simplenote lib list
|
||||
|
||||
# Listar con padre
|
||||
simplenote lib list --parent 550e8400...
|
||||
|
||||
# Ver contenido
|
||||
simplenote lib get 550e8400...
|
||||
|
||||
# Crear
|
||||
simplenote lib create --name "API Specs"
|
||||
simplenote lib create --name "Sub Librería" --parent 550e8400...
|
||||
|
||||
# Ver árbol completo
|
||||
simplenote lib tree 550e8400...
|
||||
```
|
||||
|
||||
### 4.3 Tags
|
||||
|
||||
```bash
|
||||
# Listar todos los tags
|
||||
simplenote tag list
|
||||
|
||||
# Ver docs con tag
|
||||
simplenote tag docs backend
|
||||
```
|
||||
|
||||
### 4.4 Auth
|
||||
|
||||
```bash
|
||||
# Login con token
|
||||
simplenote auth login snk_xxxxx
|
||||
|
||||
# Verificar status
|
||||
simplenote auth status
|
||||
```
|
||||
|
||||
## 5. Manejo de Errores
|
||||
|
||||
```javascript
|
||||
// Errores de API se transforman en mensajes claros
|
||||
try {
|
||||
await client.getDocument('non-existent-id');
|
||||
} catch (err) {
|
||||
console.error(err.message);
|
||||
// "API Error 404: Document not found"
|
||||
}
|
||||
```
|
||||
|
||||
Códigos de error CLI:
|
||||
- `1` — Error general (network, parse, etc)
|
||||
- `2` — Token inválido / auth fallida
|
||||
- `3` — Recurso no encontrado (404)
|
||||
- `4` — Validación de input
|
||||
|
||||
## 6. Configuración de Conexión
|
||||
|
||||
```javascript
|
||||
// ~/.config/simplenote/config.json
|
||||
{
|
||||
"apiUrl": "http://localhost:3000/api/v1",
|
||||
"token": "snk_xxxxx",
|
||||
"activeLibrary": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
Override por línea de comandos:
|
||||
```bash
|
||||
simplenote --api-url http://custom:3000/api/v1 doc list
|
||||
```
|
||||
|
||||
## 7. Dependencias CLI
|
||||
|
||||
```json
|
||||
// package.json
|
||||
{
|
||||
"dependencies": {
|
||||
"commander": "^11.1.0",
|
||||
"axios": "^1.6.0",
|
||||
"chalk": "^5.3.0",
|
||||
"inquirer": "^9.2.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8. Ejemplo de Sesión Completa
|
||||
|
||||
```bash
|
||||
$ simplenote auth login snk_a1b2c3d4e5f6
|
||||
✓ Token verified. Logged in.
|
||||
|
||||
$ simplenote lib list
|
||||
[
|
||||
{ "id": "550e8400...", "name": "Backend Requirements", "documentCount": 5 }
|
||||
]
|
||||
|
||||
$ simplenote doc create \
|
||||
--title "Token Auth" \
|
||||
--tags "backend,auth" \
|
||||
--type requirement \
|
||||
--library 550e8400...
|
||||
{
|
||||
"id": "770e8400...",
|
||||
"title": "Token Auth",
|
||||
"tags": ["backend", "auth"],
|
||||
...
|
||||
}
|
||||
|
||||
$ simplenote tag docs backend
|
||||
[
|
||||
{ "id": "770e8400...", "title": "Token Auth", ... }
|
||||
]
|
||||
|
||||
$ simplenote doc get 770e8400...
|
||||
# Muestra documento formateado con content + metadata
|
||||
```
|
||||
Reference in New Issue
Block a user