# Package manifest — every path, marked folder or file

**20 folders · 51 files.** Nothing else.

## Read this first

**`SearchConsole` is a FILE, not a folder.** It is `src/Providers/SearchConsole.php` —
a PHP class that talks to the Google Search Console API. The same applies to
`RobotsTxt`, `UrlNormalizer`, `PageParser`, `Crawler`, `AiAccessProbe`,
`CheckRunner`, `Scorer` and `AuditService`: all of them are `.php` files inside
`src/Audit/`, not directories.

In the tree diagram in the integration guide, names listed after the `←` arrow
were the *contents* of the folder on that line. That was ambiguous, and this
file replaces it.

**You do not need to create any of these folders by hand.** They all exist
inside the zip. Extract it and the structure is there. Nothing in the package
expects a folder to already be present on your server.

## Full listing

| Type | Path | Size | Web-accessible? | What it is |
|---|---|---|---|---|
| file | `.env.example` | 4 KB | NO | Template for your credentials file. Copy to .env and fill in. NEVER commit .env. |
| file | `.gitignore` | 0 KB | n/a | Keeps .env, vendor/, node_modules/ and logs out of git. |
| file | `.htaccess` | 4 KB | n/a | Apache rules for when the front controller sits AT the app root — YOUR layout. Blocks source, config, bin, var and every numbered folder. |
| file | `INTEGRATION-GUIDE.md` | 28 KB | NO | Full deployment and API wiring guide. Read section 1 for paths, 2 for MySQL. |
| file | `preflight.php` | 11 KB | YES (temporarily) | **Blank-500 diagnostic.** PHP 5.4-compatible so it runs on ANY version. Upload to /aiseo/, open in a browser, then DELETE it. |
| file | `README.md` | 3 KB | NO | Quick start, five commands. |
| file | `bootstrap.php` | 5 KB | NO | THE ANCHOR. Autoloader + .env + error handling. Every entry point requires this one file, and AISEO_ROOT is the folder that holds it. |
| **FOLDER** | `bin/` |  | NO | CLI scripts. Run from the shell or cron. Never from a browser. |
| file | `bin/audit.php` | 5 KB | NO | CLI: run an audit now. php bin/audit.php --site=1 --type=canary |
| file | `bin/doctor.php` | 14 KB | NO | CLI: environment check. RUN THIS FIRST. Prints resolved paths, diagnoses MySQL, probes whether .env is web-readable. |
| file | `bin/migrate.php` | 2 KB | NO | CLI: apply the SQL migrations. php bin/migrate.php |
| file | `bin/worker.php` | 4 KB | NO | CLI: the cron process that actually crawls. Nothing happens without it. |
| **FOLDER** | `config/` |  | NO | Path configuration. Not web-accessible. |
| file | `config/path-resolver.php` | 9 KB | NO | Finds your folders (src, templates, migrations, public, var) wherever they are. Runs before the autoloader exists, which is why it is not in src/. |
| file | `config/paths.php` | 2 KB | NO | Optional: set your folder paths explicitly here instead of in .env. |
| **FOLDER** | `db/` |  | NO | Container for migrations. |
| **FOLDER** | `db/migrations/` |  | NO | The .sql files. |
| file | `db/migrations/001_core.sql` | 27 KB | NO | Database schema. 36 tables. |
| file | `db/migrations/002_seed.sql` | 39 KB | NO | Reference data: check definitions, AI crawler registry, country config, directory blocklist. This is CONFIG — edit and re-run to tune weights. |
| **FOLDER** | `public/` |  | YES | THE ONLY WEB-ACCESSIBLE FOLDER. In your layout its contents sit at /aiseo/ directly. |
| file | `public/.htaccess` | 2 KB | n/a | Apache rules for when the document root points at public/. Use this OR the root .htaccess, not both. |
| file | `public/index.php` | 17 KB | YES | FRONT CONTROLLER. The only PHP file the browser ever hits. All pages and the JSON API. |
| file | `public/styleguide.html` | 31 KB | YES | Standalone component reference, both themes. Open it directly in a browser; needs no PHP or database. |
| **FOLDER** | `public/assets/` |  | YES | CSS and JS served to the browser. |
| **FOLDER** | `public/assets/css/` |  | YES | Stylesheets. |
| file | `public/assets/css/app.css` | 38 KB | YES | All components: shell, cards, tables, badges, gauges, meters, matrix, charts. |
| file | `public/assets/css/tokens.css` | 12 KB | YES | Design tokens. The ONLY file where a colour value may appear. |
| **FOLDER** | `public/assets/js/` |  | YES | JavaScript. |
| file | `public/assets/js/app.js` | 8 KB | YES | Theme toggle, run-audit button, progress poller, finding status. No framework. |
| **FOLDER** | `render-service/` |  | NO | Optional Node service. Runs as a separate process, not via the web server. |
| file | `render-service/package.json` | 0 KB | NO | Node dependencies for the render plane (Playwright only). |
| file | `render-service/server.mjs` | 13 KB | NO | Headless Chromium service. Provides the retrievability-gap diff. Optional — without it you still get ~85% of the checks. |
| **FOLDER** | `src/` |  | NO | All PHP classes. On your server this is 3-source-code/src. |
| **FOLDER** | `src/Audit/` |  | NO | 8 class files: the crawler, parsers, checks and scorer. |
| file | `src/Audit/AiAccessProbe.php` | 17 KB | NO | The AI crawler access matrix + the live user-agent probe. |
| file | `src/Audit/AuditService.php` | 12 KB | NO | Orchestrates one audit run end to end. Controllers and CLI talk only to this. |
| file | `src/Audit/CheckRunner.php` | 26 KB | NO | Post-crawl checks: duplicates, canonicals, titles, thin content, links, AI structure. |
| file | `src/Audit/Crawler.php` | 19 KB | NO | The crawl plane. Fetching, politeness, sitemap seeding, trap defence. |
| file | `src/Audit/PageParser.php` | 18 KB | NO | One DOM pass per page; extracts every on-page signal the checks need. |
| file | `src/Audit/RobotsTxt.php` | 14 KB | NO | RFC 9309 robots.txt parser. Covered by tests/robots_test.php. |
| file | `src/Audit/Scorer.php` | 14 KB | NO | Scoring model, hard gates, priority queue, run-to-run diff. |
| file | `src/Audit/UrlNormalizer.php` | 8 KB | NO | URL normalisation. Without it 5,000 pages become 40,000 "unique" URLs. |
| **FOLDER** | `src/Core/` |  | NO | 3 class files: Env, Logger, Queue. |
| file | `src/Core/Env.php` | 4 KB | NO | Reads .env. Covered by tests/env_test.php. |
| file | `src/Core/Logger.php` | 3 KB | NO | JSON-lines log with secret redaction. |
| file | `src/Core/Queue.php` | 4 KB | NO | Database-backed job queue. |
| **FOLDER** | `src/Db/` |  | NO | 2 class files: Database, Migrator. |
| file | `src/Db/Database.php` | 9 KB | NO | PDO connection. Turns "connection failed" into an actual diagnosis. |
| file | `src/Db/Migrator.php` | 5 KB | NO | Runs the .sql files once each, quote-aware statement splitter. |
| **FOLDER** | `src/Http/` |  | NO | 4 class files: HttpClient, HttpResponse, Router, View. |
| file | `src/Http/HttpClient.php` | 12 KB | NO | All outbound HTTP: retry, cache, cost metering, daily budget stop. |
| file | `src/Http/HttpResponse.php` | 5 KB | NO | Response object. Repeated headers, TLS expiry, robots directives. |
| file | `src/Http/Router.php` | 2 KB | NO | Tiny regex router. |
| file | `src/Http/View.php` | 3 KB | NO | Template renderer + escaping helpers. |
| **FOLDER** | `src/Providers/` |  | NO | 4 class files: one per external API. |
| file | `src/Providers/DataForSeo.php` | 15 KB | NO | DataForSEO adapter: SERP, competitors, keywords, intent, AI Mode. |
| file | `src/Providers/GoogleOAuth.php` | 7 KB | NO | Google OAuth flow for Search Console and GA4. |
| file | `src/Providers/GooglePerformance.php` | 11 KB | NO | PageSpeed Insights + Chrome UX Report (Core Web Vitals). |
| file | `src/Providers/SearchConsole.php` | 11 KB | NO | Google Search Console API: clicks per URL, cannibalisation, URL inspection. |
| **FOLDER** | `templates/` |  | NO | Plain-PHP views. On your server this is 3-source-code/templates. |
| **FOLDER** | `templates/layout/` |  | NO | The page shell. |
| file | `templates/layout/app.php` | 3 KB | NO | Page shell: <head>, sidebar include, topbar, DB-down banner. |
| **FOLDER** | `templates/pages/` |  | NO | One file per page. |
| file | `templates/pages/dashboard.php` | 7 KB | NO | Portfolio page. |
| file | `templates/pages/error.php` | 0 KB | NO | 404 page. |
| file | `templates/pages/integrations.php` | 5 KB | NO | Integrations page. |
| file | `templates/pages/site.php` | 14 KB | NO | Site detail: scores, priority queue, AI crawler matrix. |
| **FOLDER** | `templates/partials/` |  | NO | Reusable fragments. |
| file | `templates/partials/sidebar.php` | 3 KB | NO | Left navigation and site list. |
| **FOLDER** | `tests/` |  | NO | Two test scripts. Run them after any change. |
| file | `tests/env_test.php` | 4 KB | NO | 17 assertions on the .env parser. |
| file | `tests/robots_test.php` | 6 KB | NO | 33 assertions on the robots.txt parser. |

---

## Which folder do I copy this into?

**Not `public_html/aiseo/`** — that folder already holds your working app, and
both apps want to own `index.php`.

**Copy the whole tree, unchanged, into `public_html/aiseo-new/`.** Nothing needs
rearranging, your current site keeps running, and you switch over with two edited
lines once the new one works. Full steps in `deploy/DEPLOY.md`.

The table below is only for the other case — merging into the existing `/aiseo/`
folder, where the contents of `public/` have to move up a level.

## Where each folder goes if you merge into the existing /aiseo/

Your hosting keeps source at `/aiseo/3-source-code/src`, and your front
controller is served at `/aiseo/`. So the package folders map like this:

| Package folder | Put it here on your server | Must it be web-readable? |
|---|---|---|
| `src/` | `/aiseo/3-source-code/src/` — **you already have this** | **NO** |
| `templates/` | `/aiseo/3-source-code/templates/` | **NO** |
| `db/migrations/` | `/aiseo/3-source-code/db/migrations/` | **NO** |
| `config/` | `/aiseo/config/` | **NO** |
| `bin/` | `/aiseo/bin/` | **NO** |
| `tests/` | `/aiseo/tests/` | **NO** |
| `render-service/` | `/aiseo/render-service/` (or anywhere; it is a separate process) | **NO** |
| `var/` | `/aiseo/var/` — better still, `/home/dolrad/aiseo-var/` outside the web root | **NO** |
| contents of `public/` | `/aiseo/` directly — `index.php`, `assets/`, `styleguide.html` | **YES** |
| `bootstrap.php` | `/aiseo/bootstrap.php` | **NO** |
| `.env` | `/aiseo/.env` (chmod 600) | **NO** |
| `.htaccess` | `/aiseo/.htaccess` | n/a |

Note the last-but-two row: the **contents** of `public/` move up to `/aiseo/`,
because that is where your front controller already lives. Do not create a
`/aiseo/public/` folder — you would end up serving the app at
`/aiseo/public/`.

### The 8 folders you actually create

Assuming `/aiseo/` and `/aiseo/3-source-code/src/` already exist:

```
/aiseo/config/
/aiseo/bin/
/aiseo/tests/
/aiseo/var/                       (or outside the web root)
/aiseo/assets/css/
/aiseo/assets/js/
/aiseo/3-source-code/templates/
/aiseo/3-source-code/db/migrations/
```

Extracting the zip creates all of them. This list is only so you can eyeball
what changed.

### Then tell the app where things are

```
AISEO_SRC_DIR=/home/dolrad/public_html/aiseo/3-source-code/src
AISEO_TEMPLATES_DIR=/home/dolrad/public_html/aiseo/3-source-code/templates
AISEO_MIGRATIONS_DIR=/home/dolrad/public_html/aiseo/3-source-code/db/migrations
AISEO_PUBLIC_DIR=/home/dolrad/public_html/aiseo
AISEO_VAR_DIR=/home/dolrad/aiseo-var
```

Adjust `/home/dolrad/public_html` to your real account path — check it with
`pwd` in the cPanel terminal or File Manager. If you leave these blank the app
discovers the layout anyway; setting them is faster and fails loudly if wrong.

### Confirm it worked

```
php bin/doctor.php
```

The **RESOLVED PATHS** section prints exactly which folder it found for each
role. If a line says `FAIL`, that folder is not where the app is looking — and
the message names the path it tried.

---

## The 4 file types in this package

| Extension | Count | Runs how |
|---|---|---|
| `.php` | 34 | Only `public/index.php` is reached by a browser. Everything in `src/` and `templates/` is loaded BY that file. Everything in `bin/` and `tests/` runs from the shell. |
| `.sql` | 2 | Applied once each by `php bin/migrate.php`. Never executed by the web server. |
| `.css` / `.js` / `.html` | 4 | Served directly to the browser from `assets/`. |
| `.md` / `.json` / `.example` / `.htaccess` / `.gitignore` / `.mjs` | 11 | Documentation, config, and the Node render service. |
