chore: echte Appwrite-Projekt-ID übernehmen

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-04 09:38:32 +00:00
1 parent 38b361ad7a
commit 94f6d74249
7 files changed
+49 -24

No files matched your search

+19 -7
View File
@@ -29,7 +29,6 @@
import { pathToFileURL } from 'node:url';
export const DEFAULT_ENDPOINT = 'https://appwrite.webklar.com/v1';
const PROJECT = 'aircard';
// ---------------------------------------------------------------------------
// Soll-Zustand
@@ -166,11 +165,11 @@ function createApi({ endpoint, key, project }) {
}
/** Klare deutsche Meldung für eine unerwartete Antwort. */
function describeFailure(status, body, what) {
function describeFailure(status, body, what, project) {
const detail = [body?.type, body?.message].filter((part) => typeof part === 'string' && part).join(': ');
const tail = detail ? ` Server: ${detail}` : '';
if (status === 404 && body?.type === 'project_not_found') {
return `Das Projekt „${PROJECT}“ existiert auf dem Server nicht. Bitte zuerst docs/appwrite-console.md abarbeiten (Projekt mit der ID „${PROJECT}“ anlegen).`;
return `Das Projekt „${project}” existiert auf dem Server nicht. Bitte zuerst docs/appwrite-console.md abarbeiten und die AIRCARD_APPWRITE_PROJECT_ID in /home/webklar/apps/.env prüfen.`;
}
if (status === 401 || status === 403) {
return `${what}: Zugriff verweigert (HTTP ${status}). API-Key und Scopes prüfen (databases, tables, columns, buckets – jeweils read/write).${tail}`;
@@ -184,13 +183,13 @@ async function getObject(ctx, path, what) {
const res = await ctx.api('GET', path);
if (res.status === 200) return res.body;
if (isMissing(res.status, res.body)) return null;
throw new SetupError(describeFailure(res.status, res.body, what));
throw new SetupError(describeFailure(res.status, res.body, what, ctx.project));
}
async function createObject(ctx, path, body, what) {
const res = await ctx.api('POST', path, body);
if (res.status >= 200 && res.status < 300) return res.body;
throw new SetupError(describeFailure(res.status, res.body, what));
throw new SetupError(describeFailure(res.status, res.body, what, ctx.project));
}
// ---------------------------------------------------------------------------
@@ -359,18 +358,22 @@ export async function ensureBucket(ctx) {
export async function main({
endpoint = DEFAULT_ENDPOINT,
key,
project = PROJECT,
project,
check = false,
log = console.log,
pollMs = 1000,
timeoutMs = 30_000,
} = {}) {
if (!project) {
throw new SetupError('project-Parameter erforderlich');
}
const stats = { missing: 0, deviations: 0 };
const ctx = {
api: createApi({ endpoint, key, project }),
check,
pollMs,
timeoutMs,
project,
ok: (label) => log(`OK: ${label}`),
created: (label) => log(`ANGELEGT: ${label}`),
missing: (label) => {
@@ -426,7 +429,15 @@ async function cli() {
const key = process.env.AIRCARD_APPWRITE_API_KEY?.trim();
if (!key) {
console.error('Fehler: AIRCARD_APPWRITE_API_KEY fehlt.');
console.error('Den API-Key „aircard-provision“ als Zeile AIRCARD_APPWRITE_API_KEY=… in /home/webklar/apps/.env eintragen (siehe docs/appwrite-console.md)');
console.error('Den API-Key „aircard-provision” als Zeile AIRCARD_APPWRITE_API_KEY=… in /home/webklar/apps/.env eintragen (siehe docs/appwrite-console.md)');
console.error('und das Skript mit --env-file=/home/webklar/apps/.env starten.');
process.exitCode = 2;
return;
}
const project = process.env.AIRCARD_APPWRITE_PROJECT_ID?.trim();
if (!project) {
console.error('Fehler: AIRCARD_APPWRITE_PROJECT_ID fehlt.');
console.error('Die Projekt-ID als Zeile AIRCARD_APPWRITE_PROJECT_ID=6ac2130a00289343d6d5 in /home/webklar/apps/.env eintragen.');
console.error('und das Skript mit --env-file=/home/webklar/apps/.env starten.');
process.exitCode = 2;
return;
@@ -434,6 +445,7 @@ async function cli() {
process.exitCode = await main({
endpoint: process.env.AIRCARD_APPWRITE_ENDPOINT || DEFAULT_ENDPOINT,
key,
project,
check: args.includes('--check'),
});
}
+18 -9
View File
@@ -25,7 +25,7 @@ const KEY = 'test-key-0123456789abcdef-geheim';
// Fake-Appwrite (1.8-ähnliche REST-Formen, alles im Speicher)
// ---------------------------------------------------------------------------
function createFakeAppwrite({ project = 'aircard', key = KEY, stuckColumns = false, inject = null } = {}) {
function createFakeAppwrite({ project = '6ac2130a00289343d6d5', key = KEY, stuckColumns = false, inject = null } = {}) {
const state = {
databases: new Map(),
tables: new Map(), // "db/table"
@@ -158,7 +158,7 @@ async function run(fake, opts = {}) {
const code = await main({
endpoint: fake.endpoint,
key: KEY,
project: 'aircard',
project: '6ac2130a00289343d6d5',
check: false,
log: (line) => lines.push(line),
pollMs: 1,
@@ -385,7 +385,7 @@ describe('main gegen Fake-Server', () => {
// Jede Anfrage trägt die drei Header
for (const r of fake.state.requests) {
assert.equal(r.headers['content-type'], 'application/json');
assert.equal(r.headers['x-appwrite-project'], 'aircard');
assert.equal(r.headers['x-appwrite-project'], '6ac2130a00289343d6d5');
assert.equal(r.headers['x-appwrite-key'], KEY);
}
// Der Key taucht nie in der Ausgabe auf
@@ -445,15 +445,15 @@ describe('main gegen Fake-Server', () => {
test('404 project_not_found bricht klar ab und meldet nichts als fehlend', async () => {
await withFake({ project: 'anderes-projekt' }, async (fake) => {
for (const check of [true, false]) {
const { code, lines } = await run(fake, { check });
const { code, lines } = await run(fake, { check, project: '6ac2130a00289343d6d5' });
assert.equal(code, 2);
assert.equal(startsWith(lines, 'FEHLT').length, 0);
assert.equal(startsWith(lines, 'ANGELEGT').length, 0);
const abort = startsWith(lines, 'ABBRUCH');
assert.equal(abort.length, 1);
assert.match(abort[0], /Projekt/);
assert.match(abort[0], /aircard/);
assert.match(abort[0], /docs\/appwrite-console\.md/);
assert.match(abort[0], /6ac2130a00289343d6d5/);
assert.match(abort[0], /AIRCARD_APPWRITE_PROJECT_ID/);
assert.ok(!lines.join('\n').includes(KEY));
}
assert.equal(fake.posts().length, 0);
@@ -538,15 +538,23 @@ describe('main gegen Fake-Server', () => {
describe('CLI', () => {
test('ohne AIRCARD_APPWRITE_API_KEY: deutsche Fehlermeldung, Exit 2', async () => {
const { code, stdout, stderr } = await runCli([], {});
const { code, stdout, stderr } = await runCli([], { AIRCARD_APPWRITE_PROJECT_ID: '6ac2130a00289343d6d5' });
assert.equal(code, 2);
assert.equal(stdout, '');
assert.match(stderr, /AIRCARD_APPWRITE_API_KEY/);
assert.match(stderr, /fehlt/);
});
test('ohne AIRCARD_APPWRITE_PROJECT_ID: deutsche Fehlermeldung, Exit 2', async () => {
const { code, stdout, stderr } = await runCli([], { AIRCARD_APPWRITE_API_KEY: KEY });
assert.equal(code, 2);
assert.equal(stdout, '');
assert.match(stderr, /AIRCARD_APPWRITE_PROJECT_ID/);
assert.match(stderr, /fehlt/);
});
test('unbekannte Option: Exit 2', async () => {
const { code, stderr } = await runCli(['--foo'], { AIRCARD_APPWRITE_API_KEY: KEY });
const { code, stderr } = await runCli(['--foo'], { AIRCARD_APPWRITE_API_KEY: KEY, AIRCARD_APPWRITE_PROJECT_ID: '6ac2130a00289343d6d5' });
assert.equal(code, 2);
assert.match(stderr, /Unbekannte Option/);
assert.ok(!stderr.includes(KEY));
@@ -556,6 +564,7 @@ describe('CLI', () => {
await withFake({}, async (fake) => {
const { code, stdout, stderr } = await runCli(['--check'], {
AIRCARD_APPWRITE_API_KEY: KEY,
AIRCARD_APPWRITE_PROJECT_ID: '6ac2130a00289343d6d5',
AIRCARD_APPWRITE_ENDPOINT: fake.endpoint,
});
assert.equal(code, 1);
@@ -568,7 +577,7 @@ describe('CLI', () => {
test('Anlegen und danach --check über die Kommandozeile: Exit 0', async () => {
await withFake({}, async (fake) => {
const env = { AIRCARD_APPWRITE_API_KEY: KEY, AIRCARD_APPWRITE_ENDPOINT: fake.endpoint };
const env = { AIRCARD_APPWRITE_API_KEY: KEY, AIRCARD_APPWRITE_PROJECT_ID: '6ac2130a00289343d6d5', AIRCARD_APPWRITE_ENDPOINT: fake.endpoint };
const apply = await runCli([], env);
assert.equal(apply.code, 0, apply.stdout + apply.stderr);
const check = await runCli(['--check'], env);
+1 -1
View File
@@ -3,7 +3,7 @@
import { Account, Client, Storage, TablesDB } from 'appwrite';
export const APPWRITE_ENDPOINT: string = import.meta.env.VITE_APPWRITE_ENDPOINT || `${location.origin}/v1`;
export const APPWRITE_PROJECT: string = import.meta.env.VITE_APPWRITE_PROJECT_ID || 'aircard';
export const APPWRITE_PROJECT: string = import.meta.env.VITE_APPWRITE_PROJECT_ID || '6ac2130a00289343d6d5';
/** Datenbank, Tabelle und Bucket des Projekts (siehe web/scripts/appwrite-setup.mjs). */
export const IDS = { database: 'aircard', table: 'cards', bucket: 'card-images' } as const;