# فضاء الكتب — Architecture notes (MVP → full stack)

Arabic-first digital library discovery + reading for **Al-Mahir Platform**.  
**Legal constraint:** index / link **authorized** sources only (public domain, open licenses, or explicit reuse permission). No piracy aggregation.

**Alias note:** User «ليبرراري» → **Open Library** (`openlibrary.org`), enabled. **Library Genesis (LibGen)** is refused. LibriVox / LibreTexts are unrelated legal projects and remain enabled.

**Arabic sources policy:** Shamela = link/index only (no mirror/cache). noor-book.com = refused for crawl/cache (piracy risk — not “any free download site”).

**Live sync providers (`js/legal-sync.js`):** Gutendex/Gutenberg, Open Library, Internet Archive (PD/CC filters), Wikisource (MediaWiki API), DOAB, Standard Ebooks OPDS, plus Shamela portal bookmark (no scrape).

**Taxonomy:** أقسام مستوحاة من المكتبة الشاملة (`data/taxonomy-shamela.json` + `js/taxonomy.js`): عقيدة، تفاسير، حديث، فقه المذاهب، سير، تاريخ، تراجم، أدب، لغة، نحو، شعر، طب، … + أقسام حديثة (علوم، تقنية، أطفال، قانون، تعليم، فلسفة).

**Arabic catalog:** build with `tools/build_arabic_catalog.py` → `data/catalog-arabic.json`. Live «مزامنة عربية» hits OL `language:ara`, Gutendex `ar`, IA Arabic free texts, and Arabic Wikisource.

## Current deploy reality

- **Production host: Oracle** — public URL `https://oracle-api.emailcore.app/mahir/` (VM path `/opt/al-mahir-platform`, see root `ORACLE_DEPLOY.md`).
- Legacy Render static URLs (`*.onrender.com`) are obsolete and must not be used for ops.
- MVP ships as static HTML/CSS/JS under `فضاء_الكتب/` with JSON seed data.
- Reader progress, bookmarks, notes, highlights, and personal library use **localStorage** (device-local).

## MVP data shape

### Book (`data/catalog.json`)

| Field | Purpose |
|--------|---------|
| `id` | Stable key |
| `title` / `titleAr` | Display titles |
| `author` / `authorAr` | Authors |
| `category` | Filter facet |
| `language` / `languageLabel` | Language facet |
| `cover` | Cover image URL |
| `fileUrl` | Direct PDF (when CORS allows in-browser PDF.js) |
| `sourceUrl` | Canonical legal source page |
| `sourceId` | FK to sources list |
| `license` / `licenseLabelAr` | Legal label shown in UI |
| `allowCopyExcerpt` / `allowDownload` | Feature flags per item |
| `externalOnly` | Link-out only (no in-app PDF) |

### Source library (`data/sources.json`)

Admin-oriented curated list of **legal free-download** libraries (PD, CC/open, publisher-authorized free, national/university).  
Includes `acceptanceCriteria`, `freeBooksMeaningAr`, and `blockedExamples` (piracy/shadow libraries).  
Fields: `category`, `region`, `downloadAllowed`, `indexNotesAr`, `crawlStatus`, `enabled`.

### Acceptance criteria (summary)

1. Documentable legal free basis (PD / open license / publisher or library authorization).  
2. Respect robots.txt, ToS, rate limits.  
3. Per-item review for mixed collections.  
4. Reject piracy/shadow libraries even if labeled “free”.

## Future backend (when leaving Static Site)

Suggested stack (matches product brief; not implemented here):

1. **API** — Django / Laravel / Node  
2. **DB** — Postgres (catalog, users, progress) or Mongo for flexible metadata  
3. **Search** — OpenSearch / Elasticsearch for instant + smart search  
4. **Indexer worker** — periodic jobs that:
   - only crawl `sources` with `enabled=true` and documented legal basis
   - respect robots.txt / ToS / rate limits
   - store normalized book records + license evidence
5. **Object storage** — optional cached PDFs **only** when redistribution is allowed  
6. **Auth** — personal library + progress sync across devices  
7. **Reader** — keep PDF.js; move annotations to API

### Suggested tables (sketch)

- `source_libraries(id, name, base_url, license_policy, enabled, last_crawl_at)`
- `books(id, source_id, title, author, category, language, cover_url, file_url, license, …)`
- `user_progress(user_id, book_id, last_page, updated_at)`
- `user_annotations(user_id, book_id, type, page, payload, created_at)`

## Local book cache (static MVP)

- **IndexedDB** (`mahir_book_cache_v1`) stores PDF blobs by book id after same-origin fetch or user file import.
- Reader opens **cache first** → PDF.js (no CORS on re-open / offline-ish).
- If remote PDF is blocked by CORS: show legal **Archive.org embed / HTML** in an iframe immediately; user can still «تحميل للكاش» when `corsOk`/same-origin, or «استيراد إلى الكاش» after a legal download.
- Seed same-origin PDF: `pdfs/demo-tracemonkey.pdf`.

## CORS note (static MVP)

Remote PDFs often block browser `fetch` from other origins. The reader:

1. Tries PDF.js in-page load  
2. On failure, offers **legal download / original source** links  

A future API can proxy or host permitted files with correct CORS/`Content-Type`.

## Advanced features status

| Feature | Status |
|---------|--------|
| Catalog + instant client search | Done (MVP) |
| PDF.js reader, zoom, page nav | Done |
| In-text find | Done (page-level) |
| Last page / bookmarks / notes / highlights | Done (localStorage) |
| Download + copy excerpt flags | Done |
| Legal disclaimer + admin source mock | Done |
| Night mode (reader chrome) | Done (stub-level) |
| Smart search / similar books | Stub / planned (needs OpenSearch) |
| Cloud personal library + sync | Stub (local toggle only) |
| TTS / auto quotes | Planned |

## Local run

From repo root:

```bash
python -m http.server 8080
```

Then open: `http://localhost:8080/فضاء_الكتب/`

Or use existing `start_server.bat` / `server.py` if preferred.
