Account export / restore-into-new-tree / delete
New account_service + endpoints under /users/me: - GET /me/export — zip of every owned tree (account.json + media blobs). - POST /me/import — restore a backup into NEW trees (ids remapped, media re-uploaded); non-destructive, never touches existing data. - DELETE /me — soft-delete the user, their owned trees, and revoke sessions; guarded by retyping the account email. Settings page wires all three (export download, restore upload, delete with typed-email confirmation). No migration — uses existing tables + soft-delete. 52 backend tests pass (export→restore round-trip + delete guards); frontend builds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Vendored
+142
-1
@@ -168,7 +168,12 @@ export interface paths {
|
||||
get: operations["read_me_api_v1_users_me_get"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
/**
|
||||
* Delete Account
|
||||
* @description Delete the account: the user, their owned trees, and their sessions.
|
||||
* Requires retyping the account email as a guard.
|
||||
*/
|
||||
delete: operations["delete_account_api_v1_users_me_delete"];
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
@@ -194,6 +199,46 @@ export interface paths {
|
||||
patch: operations["set_self_person_api_v1_users_me_self_person_patch"];
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/users/me/export": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
/**
|
||||
* Export Account
|
||||
* @description Download a full backup (JSON + media) of every tree the user owns.
|
||||
*/
|
||||
get: operations["export_account_api_v1_users_me_export_get"];
|
||||
put?: never;
|
||||
post?: never;
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/users/me/import": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
get?: never;
|
||||
put?: never;
|
||||
/**
|
||||
* Import Account
|
||||
* @description Restore a previously-exported backup into new trees (non-destructive).
|
||||
*/
|
||||
post: operations["import_account_api_v1_users_me_import_post"];
|
||||
delete?: never;
|
||||
options?: never;
|
||||
head?: never;
|
||||
patch?: never;
|
||||
trace?: never;
|
||||
};
|
||||
"/api/v1/trees": {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -638,6 +683,16 @@ export interface paths {
|
||||
export type webhooks = Record<string, never>;
|
||||
export interface components {
|
||||
schemas: {
|
||||
/** Body_delete_account_api_v1_users_me_delete */
|
||||
Body_delete_account_api_v1_users_me_delete: {
|
||||
/** Confirm Email */
|
||||
confirm_email: string;
|
||||
};
|
||||
/** Body_import_account_api_v1_users_me_import_post */
|
||||
Body_import_account_api_v1_users_me_import_post: {
|
||||
/** File */
|
||||
file: string;
|
||||
};
|
||||
/** Body_import_gedcom_api_v1_trees__tree_id__gedcom_import_post */
|
||||
Body_import_gedcom_api_v1_trees__tree_id__gedcom_import_post: {
|
||||
/** File */
|
||||
@@ -1624,6 +1679,37 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
delete_account_api_v1_users_me_delete: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"application/x-www-form-urlencoded": components["schemas"]["Body_delete_account_api_v1_users_me_delete"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
204: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content?: never;
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
set_self_person_api_v1_users_me_self_person_patch: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
@@ -1657,6 +1743,61 @@ export interface operations {
|
||||
};
|
||||
};
|
||||
};
|
||||
export_account_api_v1_users_me_export_get: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody?: never;
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": unknown;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
import_account_api_v1_users_me_import_post: {
|
||||
parameters: {
|
||||
query?: never;
|
||||
header?: never;
|
||||
path?: never;
|
||||
cookie?: never;
|
||||
};
|
||||
requestBody: {
|
||||
content: {
|
||||
"multipart/form-data": components["schemas"]["Body_import_account_api_v1_users_me_import_post"];
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
/** @description Successful Response */
|
||||
200: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": {
|
||||
[key: string]: unknown;
|
||||
};
|
||||
};
|
||||
};
|
||||
/** @description Validation Error */
|
||||
422: {
|
||||
headers: {
|
||||
[name: string]: unknown;
|
||||
};
|
||||
content: {
|
||||
"application/json": components["schemas"]["HTTPValidationError"];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
list_my_trees_api_v1_trees_get: {
|
||||
parameters: {
|
||||
query?: {
|
||||
|
||||
Reference in New Issue
Block a user