@fivepixels-js/lite-api 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +93 -0
- package/README.md +537 -0
- package/dist/app.d.ts +10 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +70 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/identity.repository.d.ts +62 -0
- package/dist/auth/identity.repository.d.ts.map +1 -0
- package/dist/auth/identity.repository.js +202 -0
- package/dist/auth/identity.repository.js.map +1 -0
- package/dist/auth/identity.routes.d.ts +5 -0
- package/dist/auth/identity.routes.d.ts.map +1 -0
- package/dist/auth/identity.routes.js +56 -0
- package/dist/auth/identity.routes.js.map +1 -0
- package/dist/auth/identity.schemas.d.ts +2711 -0
- package/dist/auth/identity.schemas.d.ts.map +1 -0
- package/dist/auth/identity.schemas.js +117 -0
- package/dist/auth/identity.schemas.js.map +1 -0
- package/dist/auth/identity.service.d.ts +37 -0
- package/dist/auth/identity.service.d.ts.map +1 -0
- package/dist/auth/identity.service.js +131 -0
- package/dist/auth/identity.service.js.map +1 -0
- package/dist/auth/password.service.d.ts +15 -0
- package/dist/auth/password.service.d.ts.map +1 -0
- package/dist/auth/password.service.js +116 -0
- package/dist/auth/password.service.js.map +1 -0
- package/dist/auth/token.service.d.ts +38 -0
- package/dist/auth/token.service.d.ts.map +1 -0
- package/dist/auth/token.service.js +54 -0
- package/dist/auth/token.service.js.map +1 -0
- package/dist/cli/cli.d.ts +3 -0
- package/dist/cli/cli.d.ts.map +1 -0
- package/dist/cli/cli.js +132 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +4 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +24 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/init.d.ts +4 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +23 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -0
- package/dist/cli/commands/migrate.js +20 -0
- package/dist/cli/commands/migrate.js.map +1 -0
- package/dist/cli/commands/start.d.ts +4 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +13 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +4 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +48 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/io.d.ts +6 -0
- package/dist/cli/io.d.ts.map +1 -0
- package/dist/cli/io.js +9 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/community/contracts.d.ts +29 -0
- package/dist/community/contracts.d.ts.map +1 -0
- package/dist/community/contracts.js +41 -0
- package/dist/community/contracts.js.map +1 -0
- package/dist/community/error-handler.d.ts +3 -0
- package/dist/community/error-handler.d.ts.map +1 -0
- package/dist/community/error-handler.js +66 -0
- package/dist/community/error-handler.js.map +1 -0
- package/dist/community/errors.d.ts +10 -0
- package/dist/community/errors.d.ts.map +1 -0
- package/dist/community/errors.js +39 -0
- package/dist/community/errors.js.map +1 -0
- package/dist/community/etag.d.ts +5 -0
- package/dist/community/etag.d.ts.map +1 -0
- package/dist/community/etag.js +31 -0
- package/dist/community/etag.js.map +1 -0
- package/dist/community/input.d.ts +10 -0
- package/dist/community/input.d.ts.map +1 -0
- package/dist/community/input.js +48 -0
- package/dist/community/input.js.map +1 -0
- package/dist/community/mutation-route.d.ts +7 -0
- package/dist/community/mutation-route.d.ts.map +1 -0
- package/dist/community/mutation-route.js +47 -0
- package/dist/community/mutation-route.js.map +1 -0
- package/dist/community/schemas.d.ts +807 -0
- package/dist/community/schemas.d.ts.map +1 -0
- package/dist/community/schemas.js +100 -0
- package/dist/community/schemas.js.map +1 -0
- package/dist/community/system.schemas.d.ts +40 -0
- package/dist/community/system.schemas.d.ts.map +1 -0
- package/dist/community/system.schemas.js +30 -0
- package/dist/community/system.schemas.js.map +1 -0
- package/dist/config/config.d.ts +43 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +208 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/data-path.d.ts +2 -0
- package/dist/config/data-path.d.ts.map +1 -0
- package/dist/config/data-path.js +16 -0
- package/dist/config/data-path.js.map +1 -0
- package/dist/config/jwt-secret.d.ts +3 -0
- package/dist/config/jwt-secret.d.ts.map +1 -0
- package/dist/config/jwt-secret.js +67 -0
- package/dist/config/jwt-secret.js.map +1 -0
- package/dist/db/backup.d.ts +10 -0
- package/dist/db/backup.d.ts.map +1 -0
- package/dist/db/backup.js +51 -0
- package/dist/db/backup.js.map +1 -0
- package/dist/db/connection.d.ts +15 -0
- package/dist/db/connection.d.ts.map +1 -0
- package/dist/db/connection.js +82 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/guid-order.d.ts +2 -0
- package/dist/db/guid-order.d.ts.map +1 -0
- package/dist/db/guid-order.js +9 -0
- package/dist/db/guid-order.js.map +1 -0
- package/dist/db/migrate.d.ts +37 -0
- package/dist/db/migrate.d.ts.map +1 -0
- package/dist/db/migrate.js +145 -0
- package/dist/db/migrate.js.map +1 -0
- package/dist/db/migrations/001_schema_migrations.sql +6 -0
- package/dist/db/migrations/002_identity.sql +95 -0
- package/dist/db/migrations/003_projects.sql +62 -0
- package/dist/db/migrations/004_feedback_core.sql +236 -0
- package/dist/db/migrations/005_project_member_management.sql +55 -0
- package/dist/db/migrations/006_align_credentials.sql +33 -0
- package/dist/db/migrations/007_align_storage_values.sql +78 -0
- package/dist/db/storage-migration.d.ts +9 -0
- package/dist/db/storage-migration.d.ts.map +1 -0
- package/dist/db/storage-migration.js +79 -0
- package/dist/db/storage-migration.js.map +1 -0
- package/dist/db/transaction.d.ts +9 -0
- package/dist/db/transaction.d.ts.map +1 -0
- package/dist/db/transaction.js +14 -0
- package/dist/db/transaction.js.map +1 -0
- package/dist/errors/error-handler.d.ts +3 -0
- package/dist/errors/error-handler.d.ts.map +1 -0
- package/dist/errors/error-handler.js +50 -0
- package/dist/errors/error-handler.js.map +1 -0
- package/dist/feedbacks/feedback-workflow.service.d.ts +59 -0
- package/dist/feedbacks/feedback-workflow.service.d.ts.map +1 -0
- package/dist/feedbacks/feedback-workflow.service.js +89 -0
- package/dist/feedbacks/feedback-workflow.service.js.map +1 -0
- package/dist/feedbacks/feedback.input.d.ts +4 -0
- package/dist/feedbacks/feedback.input.d.ts.map +1 -0
- package/dist/feedbacks/feedback.input.js +25 -0
- package/dist/feedbacks/feedback.input.js.map +1 -0
- package/dist/feedbacks/feedback.repository.d.ts +48 -0
- package/dist/feedbacks/feedback.repository.d.ts.map +1 -0
- package/dist/feedbacks/feedback.repository.js +238 -0
- package/dist/feedbacks/feedback.repository.js.map +1 -0
- package/dist/feedbacks/feedback.routes.d.ts +4 -0
- package/dist/feedbacks/feedback.routes.d.ts.map +1 -0
- package/dist/feedbacks/feedback.routes.js +78 -0
- package/dist/feedbacks/feedback.routes.js.map +1 -0
- package/dist/feedbacks/feedback.schemas.d.ts +642 -0
- package/dist/feedbacks/feedback.schemas.d.ts.map +1 -0
- package/dist/feedbacks/feedback.schemas.js +131 -0
- package/dist/feedbacks/feedback.schemas.js.map +1 -0
- package/dist/feedbacks/feedback.service.d.ts +23 -0
- package/dist/feedbacks/feedback.service.d.ts.map +1 -0
- package/dist/feedbacks/feedback.service.js +74 -0
- package/dist/feedbacks/feedback.service.js.map +1 -0
- package/dist/feedbacks/feedback.types.d.ts +64 -0
- package/dist/feedbacks/feedback.types.d.ts.map +1 -0
- package/dist/feedbacks/feedback.types.js +2 -0
- package/dist/feedbacks/feedback.types.js.map +1 -0
- package/dist/page-elements/page-element.input.d.ts +7 -0
- package/dist/page-elements/page-element.input.d.ts.map +1 -0
- package/dist/page-elements/page-element.input.js +59 -0
- package/dist/page-elements/page-element.input.js.map +1 -0
- package/dist/page-elements/page-element.repository.d.ts +21 -0
- package/dist/page-elements/page-element.repository.d.ts.map +1 -0
- package/dist/page-elements/page-element.repository.js +123 -0
- package/dist/page-elements/page-element.repository.js.map +1 -0
- package/dist/page-elements/page-element.schemas.d.ts +97 -0
- package/dist/page-elements/page-element.schemas.d.ts.map +1 -0
- package/dist/page-elements/page-element.schemas.js +40 -0
- package/dist/page-elements/page-element.schemas.js.map +1 -0
- package/dist/page-elements/page-element.types.d.ts +24 -0
- package/dist/page-elements/page-element.types.d.ts.map +1 -0
- package/dist/page-elements/page-element.types.js +2 -0
- package/dist/page-elements/page-element.types.js.map +1 -0
- package/dist/plugins/auth.plugin.d.ts +3 -0
- package/dist/plugins/auth.plugin.d.ts.map +1 -0
- package/dist/plugins/auth.plugin.js +28 -0
- package/dist/plugins/auth.plugin.js.map +1 -0
- package/dist/plugins/community-api.plugin.d.ts +5 -0
- package/dist/plugins/community-api.plugin.d.ts.map +1 -0
- package/dist/plugins/community-api.plugin.js +25 -0
- package/dist/plugins/community-api.plugin.js.map +1 -0
- package/dist/plugins/cors.plugin.d.ts +3 -0
- package/dist/plugins/cors.plugin.d.ts.map +1 -0
- package/dist/plugins/cors.plugin.js +19 -0
- package/dist/plugins/cors.plugin.js.map +1 -0
- package/dist/plugins/swagger.plugin.d.ts +3 -0
- package/dist/plugins/swagger.plugin.d.ts.map +1 -0
- package/dist/plugins/swagger.plugin.js +59 -0
- package/dist/plugins/swagger.plugin.js.map +1 -0
- package/dist/plugins/user-auth.plugin.d.ts +33 -0
- package/dist/plugins/user-auth.plugin.d.ts.map +1 -0
- package/dist/plugins/user-auth.plugin.js +62 -0
- package/dist/plugins/user-auth.plugin.js.map +1 -0
- package/dist/projects/members/project-member.repository.d.ts +49 -0
- package/dist/projects/members/project-member.repository.d.ts.map +1 -0
- package/dist/projects/members/project-member.repository.js +215 -0
- package/dist/projects/members/project-member.repository.js.map +1 -0
- package/dist/projects/members/project-member.routes.d.ts +4 -0
- package/dist/projects/members/project-member.routes.d.ts.map +1 -0
- package/dist/projects/members/project-member.routes.js +82 -0
- package/dist/projects/members/project-member.routes.js.map +1 -0
- package/dist/projects/members/project-member.schemas.d.ts +2735 -0
- package/dist/projects/members/project-member.schemas.d.ts.map +1 -0
- package/dist/projects/members/project-member.schemas.js +138 -0
- package/dist/projects/members/project-member.schemas.js.map +1 -0
- package/dist/projects/members/project-member.service.d.ts +29 -0
- package/dist/projects/members/project-member.service.d.ts.map +1 -0
- package/dist/projects/members/project-member.service.js +92 -0
- package/dist/projects/members/project-member.service.js.map +1 -0
- package/dist/projects/project-access.policy.d.ts +11 -0
- package/dist/projects/project-access.policy.d.ts.map +1 -0
- package/dist/projects/project-access.policy.js +30 -0
- package/dist/projects/project-access.policy.js.map +1 -0
- package/dist/projects/project-access.repository.d.ts +12 -0
- package/dist/projects/project-access.repository.d.ts.map +1 -0
- package/dist/projects/project-access.repository.js +45 -0
- package/dist/projects/project-access.repository.js.map +1 -0
- package/dist/projects/project-access.types.d.ts +9 -0
- package/dist/projects/project-access.types.d.ts.map +1 -0
- package/dist/projects/project-access.types.js +2 -0
- package/dist/projects/project-access.types.js.map +1 -0
- package/dist/projects/project-mutation.service.d.ts +15 -0
- package/dist/projects/project-mutation.service.d.ts.map +1 -0
- package/dist/projects/project-mutation.service.js +39 -0
- package/dist/projects/project-mutation.service.js.map +1 -0
- package/dist/projects/project.repository.d.ts +49 -0
- package/dist/projects/project.repository.d.ts.map +1 -0
- package/dist/projects/project.repository.js +155 -0
- package/dist/projects/project.repository.js.map +1 -0
- package/dist/projects/project.routes.d.ts +4 -0
- package/dist/projects/project.routes.d.ts.map +1 -0
- package/dist/projects/project.routes.js +45 -0
- package/dist/projects/project.routes.js.map +1 -0
- package/dist/projects/project.schemas.d.ts +2044 -0
- package/dist/projects/project.schemas.d.ts.map +1 -0
- package/dist/projects/project.schemas.js +90 -0
- package/dist/projects/project.schemas.js.map +1 -0
- package/dist/projects/project.service.d.ts +40 -0
- package/dist/projects/project.service.d.ts.map +1 -0
- package/dist/projects/project.service.js +128 -0
- package/dist/projects/project.service.js.map +1 -0
- package/dist/replies/reply-mutation.service.d.ts +19 -0
- package/dist/replies/reply-mutation.service.d.ts.map +1 -0
- package/dist/replies/reply-mutation.service.js +51 -0
- package/dist/replies/reply-mutation.service.js.map +1 -0
- package/dist/replies/reply.input.d.ts +4 -0
- package/dist/replies/reply.input.d.ts.map +1 -0
- package/dist/replies/reply.input.js +33 -0
- package/dist/replies/reply.input.js.map +1 -0
- package/dist/replies/reply.repository.d.ts +40 -0
- package/dist/replies/reply.repository.d.ts.map +1 -0
- package/dist/replies/reply.repository.js +173 -0
- package/dist/replies/reply.repository.js.map +1 -0
- package/dist/replies/reply.routes.d.ts +4 -0
- package/dist/replies/reply.routes.d.ts.map +1 -0
- package/dist/replies/reply.routes.js +64 -0
- package/dist/replies/reply.routes.js.map +1 -0
- package/dist/replies/reply.schemas.d.ts +251 -0
- package/dist/replies/reply.schemas.d.ts.map +1 -0
- package/dist/replies/reply.schemas.js +51 -0
- package/dist/replies/reply.schemas.js.map +1 -0
- package/dist/replies/reply.service.d.ts +19 -0
- package/dist/replies/reply.service.d.ts.map +1 -0
- package/dist/replies/reply.service.js +50 -0
- package/dist/replies/reply.service.js.map +1 -0
- package/dist/replies/reply.types.d.ts +31 -0
- package/dist/replies/reply.types.d.ts.map +1 -0
- package/dist/replies/reply.types.js +2 -0
- package/dist/replies/reply.types.js.map +1 -0
- package/dist/report-cases/report-case-workflow.service.d.ts +39 -0
- package/dist/report-cases/report-case-workflow.service.d.ts.map +1 -0
- package/dist/report-cases/report-case-workflow.service.js +103 -0
- package/dist/report-cases/report-case-workflow.service.js.map +1 -0
- package/dist/report-cases/report-case.input.d.ts +4 -0
- package/dist/report-cases/report-case.input.d.ts.map +1 -0
- package/dist/report-cases/report-case.input.js +29 -0
- package/dist/report-cases/report-case.input.js.map +1 -0
- package/dist/report-cases/report-case.repository.d.ts +45 -0
- package/dist/report-cases/report-case.repository.d.ts.map +1 -0
- package/dist/report-cases/report-case.repository.js +185 -0
- package/dist/report-cases/report-case.repository.js.map +1 -0
- package/dist/report-cases/report-case.routes.d.ts +4 -0
- package/dist/report-cases/report-case.routes.d.ts.map +1 -0
- package/dist/report-cases/report-case.routes.js +94 -0
- package/dist/report-cases/report-case.routes.js.map +1 -0
- package/dist/report-cases/report-case.schemas.d.ts +294 -0
- package/dist/report-cases/report-case.schemas.d.ts.map +1 -0
- package/dist/report-cases/report-case.schemas.js +77 -0
- package/dist/report-cases/report-case.schemas.js.map +1 -0
- package/dist/report-cases/report-case.service.d.ts +21 -0
- package/dist/report-cases/report-case.service.d.ts.map +1 -0
- package/dist/report-cases/report-case.service.js +60 -0
- package/dist/report-cases/report-case.service.js.map +1 -0
- package/dist/report-cases/report-case.types.d.ts +39 -0
- package/dist/report-cases/report-case.types.d.ts.map +1 -0
- package/dist/report-cases/report-case.types.js +2 -0
- package/dist/report-cases/report-case.types.js.map +1 -0
- package/dist/routes/health.route.d.ts +4 -0
- package/dist/routes/health.route.d.ts.map +1 -0
- package/dist/routes/health.route.js +39 -0
- package/dist/routes/health.route.js.map +1 -0
- package/dist/routes/version.route.d.ts +3 -0
- package/dist/routes/version.route.d.ts.map +1 -0
- package/dist/routes/version.route.js +22 -0
- package/dist/routes/version.route.js.map +1 -0
- package/dist/runtime/index.d.ts +8 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +11 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +66 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/values.d.ts +3 -0
- package/dist/storage/values.d.ts.map +1 -0
- package/dist/storage/values.js +30 -0
- package/dist/storage/values.js.map +1 -0
- package/dist/users/current-user.routes.d.ts +3 -0
- package/dist/users/current-user.routes.d.ts.map +1 -0
- package/dist/users/current-user.routes.js +9 -0
- package/dist/users/current-user.routes.js.map +1 -0
- package/dist/users/current-user.schemas.d.ts +641 -0
- package/dist/users/current-user.schemas.d.ts.map +1 -0
- package/dist/users/current-user.schemas.js +21 -0
- package/dist/users/current-user.schemas.js.map +1 -0
- package/dist/users/user-search.repository.d.ts +19 -0
- package/dist/users/user-search.repository.d.ts.map +1 -0
- package/dist/users/user-search.repository.js +55 -0
- package/dist/users/user-search.repository.js.map +1 -0
- package/dist/users/user-search.routes.d.ts +4 -0
- package/dist/users/user-search.routes.d.ts.map +1 -0
- package/dist/users/user-search.routes.js +19 -0
- package/dist/users/user-search.routes.js.map +1 -0
- package/dist/users/user-search.schemas.d.ts +693 -0
- package/dist/users/user-search.schemas.d.ts.map +1 -0
- package/dist/users/user-search.schemas.js +41 -0
- package/dist/users/user-search.schemas.js.map +1 -0
- package/dist/users/user-search.service.d.ts +20 -0
- package/dist/users/user-search.service.d.ts.map +1 -0
- package/dist/users/user-search.service.js +41 -0
- package/dist/users/user-search.service.js.map +1 -0
- package/dist/users/user.schemas.d.ts +47 -0
- package/dist/users/user.schemas.d.ts.map +1 -0
- package/dist/users/user.schemas.js +13 -0
- package/dist/users/user.schemas.js.map +1 -0
- package/dist/users/user.types.d.ts +6 -0
- package/dist/users/user.types.d.ts.map +1 -0
- package/dist/users/user.types.js +2 -0
- package/dist/users/user.types.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/docs/guides/community-api-quickstart.md +171 -0
- package/docs/guides/feature-structure.md +138 -0
- package/docs/guides/independent-cli.md +73 -0
- package/docs/guides/non-attachment-api-contract.md +138 -0
- package/docs/plans/selfdev-schema-alignment.md +61 -0
- package/package.json +76 -0
- package/sql/fivepixels-lite-init.sql +518 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
-- Fivepixels Lite API: 최초 설치용 SQLite 통합 DDL
|
|
2
|
+
-- 기준: 현재 개발 소스 migration 001~007 (schema version 7).
|
|
3
|
+
-- SQL Server/selfdev용 SQL이 아닙니다. 기존 DB 업그레이드에 사용하지 마십시오.
|
|
4
|
+
--
|
|
5
|
+
-- 모든 테이블/인덱스/제약/마이그레이션 이력을 포함합니다.
|
|
6
|
+
-- Node.js, 앱 등록 함수, 확장 모듈이나 다른 SQL 파일이 필요하지 않습니다.
|
|
7
|
+
-- SQLite 3.38 이상(STRICT + 내장 JSON 함수), 쓰기 가능한 로컬 디스크가 필요합니다.
|
|
8
|
+
-- 최신 보안 패치 버전 사용을 권장합니다. API는 별도로 WAL 안전 버전을 검사합니다.
|
|
9
|
+
--
|
|
10
|
+
-- 실행: sqlite3 -bail /절대/신규/경로/data.db < /절대/경로/fivepixels-lite-init.sql
|
|
11
|
+
-- 새 연결에서 전체 파일을 실행하십시오. 기존 트랜잭션 안에서 실행하지 마십시오.
|
|
12
|
+
-- 오류 시 반드시 즉시 중단하고 ROLLBACK 또는 연결을 닫으십시오.
|
|
13
|
+
-- GUI 도구의 '오류 무시 후 계속 실행' 모드는 지원하지 않습니다.
|
|
14
|
+
-- 기존 스키마/데이터는 변경하거나 삭제하지 않습니다. 재실행도 오류로 거부합니다.
|
|
15
|
+
-- WAL/동기화 설정과 JWT 키 생성은 이후 같은 소스의 API init/start가 처리합니다.
|
|
16
|
+
-- DDL 자체는 관리자 계정, JWT 키, 비밀번호, 업무 샘플 데이터를 생성하지 않습니다.
|
|
17
|
+
|
|
18
|
+
PRAGMA foreign_keys = ON;
|
|
19
|
+
PRAGMA busy_timeout = 5000;
|
|
20
|
+
|
|
21
|
+
BEGIN IMMEDIATE;
|
|
22
|
+
|
|
23
|
+
-- main DB가 비었는지 쓰기 잠금 안에서 확인합니다. 임시 검사 객체는 커밋 전에 제거합니다.
|
|
24
|
+
CREATE TEMP TABLE fivepixels_init_guard (step TEXT NOT NULL) STRICT;
|
|
25
|
+
|
|
26
|
+
CREATE TEMP TRIGGER fivepixels_init_empty_database
|
|
27
|
+
BEFORE INSERT ON fivepixels_init_guard
|
|
28
|
+
WHEN NEW.step = 'empty' AND EXISTS (
|
|
29
|
+
SELECT 1 FROM main.sqlite_schema WHERE name NOT LIKE 'sqlite_%'
|
|
30
|
+
)
|
|
31
|
+
BEGIN
|
|
32
|
+
SELECT RAISE(ROLLBACK, 'fivepixels-init-requires-empty-database');
|
|
33
|
+
END;
|
|
34
|
+
|
|
35
|
+
CREATE TEMP TRIGGER fivepixels_init_foreign_keys
|
|
36
|
+
BEFORE INSERT ON fivepixels_init_guard
|
|
37
|
+
WHEN (SELECT foreign_keys FROM pragma_foreign_keys) <> 1
|
|
38
|
+
BEGIN
|
|
39
|
+
SELECT RAISE(ROLLBACK, 'fivepixels-init-requires-foreign-keys');
|
|
40
|
+
END;
|
|
41
|
+
|
|
42
|
+
CREATE TEMP TRIGGER fivepixels_init_integrity
|
|
43
|
+
BEFORE INSERT ON fivepixels_init_guard
|
|
44
|
+
WHEN NEW.step = 'verify' AND (
|
|
45
|
+
EXISTS (SELECT 1 FROM pragma_foreign_key_check)
|
|
46
|
+
OR EXISTS (SELECT 1 FROM pragma_integrity_check WHERE integrity_check <> 'ok')
|
|
47
|
+
)
|
|
48
|
+
BEGIN
|
|
49
|
+
SELECT RAISE(ROLLBACK, 'fivepixels-init-integrity-check-failed');
|
|
50
|
+
END;
|
|
51
|
+
|
|
52
|
+
INSERT INTO temp.fivepixels_init_guard (step) VALUES ('empty');
|
|
53
|
+
|
|
54
|
+
-- 최종 테이블 정의: 과거 버전의 임시 테이블 생성/변환 과정은 실행하지 않습니다.
|
|
55
|
+
CREATE TABLE schema_migrations (
|
|
56
|
+
version INTEGER PRIMARY KEY CHECK (version > 0),
|
|
57
|
+
name TEXT NOT NULL UNIQUE,
|
|
58
|
+
checksum TEXT NOT NULL CHECK (length(checksum) = 64),
|
|
59
|
+
applied_at TEXT NOT NULL
|
|
60
|
+
) STRICT;
|
|
61
|
+
|
|
62
|
+
CREATE TABLE users (
|
|
63
|
+
user_id TEXT PRIMARY KEY
|
|
64
|
+
, status_code INTEGER NOT NULL DEFAULT 1
|
|
65
|
+
, user_name TEXT NOT NULL
|
|
66
|
+
, profile_image_url TEXT
|
|
67
|
+
, created_at TEXT NOT NULL
|
|
68
|
+
, updated_at TEXT NOT NULL
|
|
69
|
+
, CHECK (
|
|
70
|
+
length(user_id) = 36
|
|
71
|
+
AND user_id = lower(user_id)
|
|
72
|
+
AND substr(user_id, 9, 1) = '-'
|
|
73
|
+
AND substr(user_id, 14, 1) = '-'
|
|
74
|
+
AND substr(user_id, 19, 1) = '-'
|
|
75
|
+
AND substr(user_id, 24, 1) = '-'
|
|
76
|
+
AND length(replace(user_id, '-', '')) = 32
|
|
77
|
+
AND replace(user_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
78
|
+
)
|
|
79
|
+
, CHECK (status_code IN (1, 2, 3))
|
|
80
|
+
, CHECK (user_name = trim(user_name) AND length(user_name) BETWEEN 1 AND 100)
|
|
81
|
+
, CHECK (
|
|
82
|
+
profile_image_url IS NULL
|
|
83
|
+
OR (profile_image_url = trim(profile_image_url) AND length(profile_image_url) BETWEEN 1 AND 2048)
|
|
84
|
+
)
|
|
85
|
+
) STRICT;
|
|
86
|
+
|
|
87
|
+
CREATE TABLE auth_refresh_tokens (
|
|
88
|
+
refresh_token_id TEXT PRIMARY KEY
|
|
89
|
+
, user_id TEXT NOT NULL
|
|
90
|
+
, token_hash BLOB NOT NULL UNIQUE
|
|
91
|
+
, expires_at TEXT NOT NULL
|
|
92
|
+
, last_used_at TEXT
|
|
93
|
+
, revoked_at TEXT
|
|
94
|
+
, replaced_by_token_id TEXT
|
|
95
|
+
, lock_version INTEGER NOT NULL DEFAULT 0
|
|
96
|
+
, created_at TEXT NOT NULL
|
|
97
|
+
, CONSTRAINT fk_auth_refresh_tokens_user FOREIGN KEY (user_id)
|
|
98
|
+
REFERENCES users (user_id) ON DELETE RESTRICT
|
|
99
|
+
, CONSTRAINT fk_auth_refresh_tokens_replacement FOREIGN KEY (replaced_by_token_id)
|
|
100
|
+
REFERENCES auth_refresh_tokens (refresh_token_id) ON DELETE RESTRICT
|
|
101
|
+
, CHECK (
|
|
102
|
+
length(refresh_token_id) = 36
|
|
103
|
+
AND refresh_token_id = lower(refresh_token_id)
|
|
104
|
+
AND substr(refresh_token_id, 9, 1) = '-'
|
|
105
|
+
AND substr(refresh_token_id, 14, 1) = '-'
|
|
106
|
+
AND substr(refresh_token_id, 19, 1) = '-'
|
|
107
|
+
AND substr(refresh_token_id, 24, 1) = '-'
|
|
108
|
+
AND length(replace(refresh_token_id, '-', '')) = 32
|
|
109
|
+
AND replace(refresh_token_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
110
|
+
)
|
|
111
|
+
, CHECK (length(token_hash) = 32)
|
|
112
|
+
, CHECK (expires_at > created_at)
|
|
113
|
+
, CHECK (
|
|
114
|
+
replaced_by_token_id IS NULL
|
|
115
|
+
OR (replaced_by_token_id <> refresh_token_id AND revoked_at IS NOT NULL)
|
|
116
|
+
)
|
|
117
|
+
, CHECK (lock_version >= 0)
|
|
118
|
+
) STRICT;
|
|
119
|
+
|
|
120
|
+
CREATE TABLE projects (
|
|
121
|
+
project_id TEXT PRIMARY KEY
|
|
122
|
+
CHECK (
|
|
123
|
+
length(project_id) = 36
|
|
124
|
+
AND substr(project_id, 9, 1) = '-'
|
|
125
|
+
AND substr(project_id, 14, 1) = '-'
|
|
126
|
+
AND substr(project_id, 19, 1) = '-'
|
|
127
|
+
AND substr(project_id, 24, 1) = '-'
|
|
128
|
+
AND project_id = lower(project_id)
|
|
129
|
+
AND length(replace(project_id, '-', '')) = 32
|
|
130
|
+
AND replace(project_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
131
|
+
),
|
|
132
|
+
creator_id TEXT NOT NULL,
|
|
133
|
+
status_code INTEGER NOT NULL DEFAULT 1
|
|
134
|
+
CHECK (status_code IN (1, 2)),
|
|
135
|
+
project_name TEXT NOT NULL
|
|
136
|
+
CHECK (
|
|
137
|
+
length(project_name) BETWEEN 1 AND 100
|
|
138
|
+
AND project_name = trim(project_name)
|
|
139
|
+
),
|
|
140
|
+
lock_version INTEGER NOT NULL DEFAULT 0
|
|
141
|
+
CHECK (lock_version >= 0),
|
|
142
|
+
created_at TEXT NOT NULL,
|
|
143
|
+
updated_at TEXT NOT NULL,
|
|
144
|
+
CONSTRAINT fk_projects_creator
|
|
145
|
+
FOREIGN KEY (creator_id) REFERENCES users(user_id)
|
|
146
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT
|
|
147
|
+
) STRICT;
|
|
148
|
+
|
|
149
|
+
CREATE TABLE project_members (
|
|
150
|
+
project_id TEXT NOT NULL,
|
|
151
|
+
user_id TEXT NOT NULL,
|
|
152
|
+
role_code INTEGER NOT NULL
|
|
153
|
+
CHECK (role_code IN (1, 2)),
|
|
154
|
+
added_by TEXT NOT NULL,
|
|
155
|
+
lock_version INTEGER NOT NULL DEFAULT 0
|
|
156
|
+
CHECK (lock_version >= 0),
|
|
157
|
+
joined_at TEXT NOT NULL,
|
|
158
|
+
updated_at TEXT NOT NULL,
|
|
159
|
+
CONSTRAINT pk_project_members PRIMARY KEY (project_id, user_id),
|
|
160
|
+
CONSTRAINT fk_project_members_project
|
|
161
|
+
FOREIGN KEY (project_id) REFERENCES projects(project_id)
|
|
162
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
163
|
+
CONSTRAINT fk_project_members_user
|
|
164
|
+
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
|
165
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
166
|
+
CONSTRAINT fk_project_members_added_by
|
|
167
|
+
FOREIGN KEY (added_by) REFERENCES users(user_id)
|
|
168
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT
|
|
169
|
+
) STRICT;
|
|
170
|
+
|
|
171
|
+
CREATE TABLE feedbacks (
|
|
172
|
+
feedback_id TEXT PRIMARY KEY,
|
|
173
|
+
project_id TEXT NOT NULL,
|
|
174
|
+
environment TEXT NOT NULL
|
|
175
|
+
CHECK (length(environment) BETWEEN 1 AND 50 AND environment = lower(trim(environment))),
|
|
176
|
+
pathname TEXT NOT NULL
|
|
177
|
+
CHECK (length(pathname) BETWEEN 1 AND 2000 AND substr(pathname, 1, 1) = '/'),
|
|
178
|
+
pathname_hash TEXT NOT NULL
|
|
179
|
+
CHECK (length(pathname_hash) = 64 AND pathname_hash NOT GLOB '*[^0-9a-f]*'),
|
|
180
|
+
report_id TEXT NOT NULL
|
|
181
|
+
CHECK (length(report_id) BETWEEN 1 AND 255 AND report_id = trim(report_id)),
|
|
182
|
+
report_type TEXT NOT NULL
|
|
183
|
+
CHECK (length(report_type) BETWEEN 1 AND 50 AND report_type = trim(report_type)),
|
|
184
|
+
target_selector TEXT
|
|
185
|
+
CHECK (target_selector IS NULL OR (length(target_selector) BETWEEN 1 AND 2000 AND target_selector = trim(target_selector))),
|
|
186
|
+
status_code INTEGER NOT NULL DEFAULT 1
|
|
187
|
+
CHECK (status_code IN (1, 2)),
|
|
188
|
+
field_values TEXT NOT NULL
|
|
189
|
+
CHECK (json_valid(field_values) AND json_type(field_values) = 'object'),
|
|
190
|
+
position TEXT NOT NULL
|
|
191
|
+
CHECK (json_valid(position) AND json_type(position) = 'object'),
|
|
192
|
+
app_version TEXT NOT NULL
|
|
193
|
+
CHECK (length(app_version) BETWEEN 1 AND 100 AND app_version = trim(app_version)),
|
|
194
|
+
author_id TEXT NOT NULL,
|
|
195
|
+
assignee_id TEXT,
|
|
196
|
+
integrations TEXT NOT NULL
|
|
197
|
+
CHECK (json_valid(integrations) AND json_type(integrations) = 'array'),
|
|
198
|
+
lock_version INTEGER NOT NULL DEFAULT 0
|
|
199
|
+
CHECK (lock_version >= 0),
|
|
200
|
+
created_at TEXT NOT NULL,
|
|
201
|
+
updated_at TEXT NOT NULL,
|
|
202
|
+
CONSTRAINT fk_feedbacks_project
|
|
203
|
+
FOREIGN KEY (project_id) REFERENCES projects(project_id)
|
|
204
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
205
|
+
CONSTRAINT fk_feedbacks_author
|
|
206
|
+
FOREIGN KEY (author_id) REFERENCES users(user_id)
|
|
207
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
208
|
+
CONSTRAINT fk_feedbacks_assignee_membership
|
|
209
|
+
FOREIGN KEY (project_id, assignee_id) REFERENCES project_members(project_id, user_id)
|
|
210
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
211
|
+
CHECK (
|
|
212
|
+
length(feedback_id) = 36
|
|
213
|
+
AND feedback_id = lower(feedback_id)
|
|
214
|
+
AND substr(feedback_id, 9, 1) = '-'
|
|
215
|
+
AND substr(feedback_id, 14, 1) = '-'
|
|
216
|
+
AND substr(feedback_id, 19, 1) = '-'
|
|
217
|
+
AND substr(feedback_id, 24, 1) = '-'
|
|
218
|
+
AND replace(feedback_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
219
|
+
)
|
|
220
|
+
) STRICT;
|
|
221
|
+
|
|
222
|
+
CREATE TABLE report_cases (
|
|
223
|
+
report_case_id TEXT PRIMARY KEY,
|
|
224
|
+
feedback_id TEXT NOT NULL,
|
|
225
|
+
type_code INTEGER NOT NULL
|
|
226
|
+
CHECK (type_code BETWEEN 1 AND 4),
|
|
227
|
+
status_code INTEGER NOT NULL DEFAULT 1
|
|
228
|
+
CHECK (status_code IN (1, 2)),
|
|
229
|
+
content TEXT NOT NULL
|
|
230
|
+
CHECK (length(content) >= 1 AND content = trim(content)),
|
|
231
|
+
creator_id TEXT NOT NULL,
|
|
232
|
+
assignee_id TEXT,
|
|
233
|
+
lock_version INTEGER NOT NULL DEFAULT 0
|
|
234
|
+
CHECK (lock_version >= 0),
|
|
235
|
+
resolved_at TEXT,
|
|
236
|
+
created_at TEXT NOT NULL,
|
|
237
|
+
updated_at TEXT NOT NULL,
|
|
238
|
+
CONSTRAINT fk_report_cases_feedback
|
|
239
|
+
FOREIGN KEY (feedback_id) REFERENCES feedbacks(feedback_id)
|
|
240
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
241
|
+
CONSTRAINT fk_report_cases_creator
|
|
242
|
+
FOREIGN KEY (creator_id) REFERENCES users(user_id)
|
|
243
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
244
|
+
CONSTRAINT fk_report_cases_assignee
|
|
245
|
+
FOREIGN KEY (assignee_id) REFERENCES users(user_id)
|
|
246
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
247
|
+
CHECK (
|
|
248
|
+
(status_code = 1 AND resolved_at IS NULL)
|
|
249
|
+
OR (status_code = 2 AND resolved_at IS NOT NULL)
|
|
250
|
+
),
|
|
251
|
+
CHECK (
|
|
252
|
+
length(report_case_id) = 36
|
|
253
|
+
AND report_case_id = lower(report_case_id)
|
|
254
|
+
AND substr(report_case_id, 9, 1) = '-'
|
|
255
|
+
AND substr(report_case_id, 14, 1) = '-'
|
|
256
|
+
AND substr(report_case_id, 19, 1) = '-'
|
|
257
|
+
AND substr(report_case_id, 24, 1) = '-'
|
|
258
|
+
AND replace(report_case_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
259
|
+
)
|
|
260
|
+
) STRICT;
|
|
261
|
+
|
|
262
|
+
CREATE TABLE replies (
|
|
263
|
+
reply_id TEXT PRIMARY KEY,
|
|
264
|
+
type_code INTEGER NOT NULL
|
|
265
|
+
CHECK (type_code BETWEEN 1 AND 9),
|
|
266
|
+
status_code INTEGER NOT NULL DEFAULT 1
|
|
267
|
+
CHECK (status_code IN (1, 2)),
|
|
268
|
+
report_case_id TEXT NOT NULL,
|
|
269
|
+
parent_reply_id TEXT,
|
|
270
|
+
content TEXT NOT NULL
|
|
271
|
+
CHECK (length(content) BETWEEN 1 AND 10000 AND content = trim(content)),
|
|
272
|
+
author_id TEXT NOT NULL,
|
|
273
|
+
assignee_id TEXT,
|
|
274
|
+
previous_assignee_id TEXT,
|
|
275
|
+
lock_version INTEGER NOT NULL DEFAULT 0
|
|
276
|
+
CHECK (lock_version >= 0),
|
|
277
|
+
deleted_at TEXT,
|
|
278
|
+
created_at TEXT NOT NULL,
|
|
279
|
+
updated_at TEXT NOT NULL,
|
|
280
|
+
CONSTRAINT uq_replies_report_case_reply UNIQUE (report_case_id, reply_id),
|
|
281
|
+
CONSTRAINT fk_replies_report_case
|
|
282
|
+
FOREIGN KEY (report_case_id) REFERENCES report_cases(report_case_id)
|
|
283
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
284
|
+
CONSTRAINT fk_replies_parent
|
|
285
|
+
FOREIGN KEY (report_case_id, parent_reply_id)
|
|
286
|
+
REFERENCES replies(report_case_id, reply_id)
|
|
287
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
288
|
+
CONSTRAINT fk_replies_author
|
|
289
|
+
FOREIGN KEY (author_id) REFERENCES users(user_id)
|
|
290
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
291
|
+
CONSTRAINT fk_replies_assignee
|
|
292
|
+
FOREIGN KEY (assignee_id) REFERENCES users(user_id)
|
|
293
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
294
|
+
CONSTRAINT fk_replies_previous_assignee
|
|
295
|
+
FOREIGN KEY (previous_assignee_id) REFERENCES users(user_id)
|
|
296
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
297
|
+
CHECK (parent_reply_id IS NULL OR parent_reply_id <> reply_id),
|
|
298
|
+
CHECK (
|
|
299
|
+
(status_code = 1 AND deleted_at IS NULL)
|
|
300
|
+
OR (status_code = 2 AND deleted_at IS NOT NULL)
|
|
301
|
+
),
|
|
302
|
+
CHECK (
|
|
303
|
+
length(reply_id) = 36
|
|
304
|
+
AND reply_id = lower(reply_id)
|
|
305
|
+
AND substr(reply_id, 9, 1) = '-'
|
|
306
|
+
AND substr(reply_id, 14, 1) = '-'
|
|
307
|
+
AND substr(reply_id, 19, 1) = '-'
|
|
308
|
+
AND substr(reply_id, 24, 1) = '-'
|
|
309
|
+
AND replace(reply_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
310
|
+
)
|
|
311
|
+
) STRICT;
|
|
312
|
+
|
|
313
|
+
CREATE TABLE page_elements (
|
|
314
|
+
page_element_id TEXT PRIMARY KEY,
|
|
315
|
+
mention_id TEXT NOT NULL UNIQUE,
|
|
316
|
+
label TEXT NOT NULL
|
|
317
|
+
CHECK (length(label) BETWEEN 1 AND 200 AND label = trim(label) AND instr(label, char(0)) = 0),
|
|
318
|
+
data_report_id TEXT
|
|
319
|
+
CHECK (data_report_id IS NULL OR (length(data_report_id) BETWEEN 1 AND 255 AND data_report_id = trim(data_report_id) AND instr(data_report_id, char(0)) = 0)),
|
|
320
|
+
selector TEXT NOT NULL
|
|
321
|
+
CHECK (length(selector) BETWEEN 1 AND 2000 AND selector = trim(selector) AND instr(selector, char(0)) = 0),
|
|
322
|
+
created_by TEXT NOT NULL,
|
|
323
|
+
created_at TEXT NOT NULL,
|
|
324
|
+
CONSTRAINT fk_page_elements_creator
|
|
325
|
+
FOREIGN KEY (created_by) REFERENCES users(user_id)
|
|
326
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
327
|
+
CHECK (
|
|
328
|
+
length(page_element_id) = 36
|
|
329
|
+
AND page_element_id = lower(page_element_id)
|
|
330
|
+
AND substr(page_element_id, 9, 1) = '-'
|
|
331
|
+
AND substr(page_element_id, 14, 1) = '-'
|
|
332
|
+
AND substr(page_element_id, 19, 1) = '-'
|
|
333
|
+
AND substr(page_element_id, 24, 1) = '-'
|
|
334
|
+
AND replace(page_element_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
335
|
+
),
|
|
336
|
+
CHECK (
|
|
337
|
+
length(mention_id) = 36
|
|
338
|
+
AND mention_id = lower(mention_id)
|
|
339
|
+
AND substr(mention_id, 9, 1) = '-'
|
|
340
|
+
AND substr(mention_id, 14, 1) = '-'
|
|
341
|
+
AND substr(mention_id, 19, 1) = '-'
|
|
342
|
+
AND substr(mention_id, 24, 1) = '-'
|
|
343
|
+
AND replace(mention_id, '-', '') NOT GLOB '*[^0-9a-f]*'
|
|
344
|
+
)
|
|
345
|
+
) STRICT;
|
|
346
|
+
|
|
347
|
+
CREATE TABLE report_case_page_elements (
|
|
348
|
+
report_case_id TEXT NOT NULL,
|
|
349
|
+
page_element_id TEXT NOT NULL,
|
|
350
|
+
CONSTRAINT pk_report_case_page_elements PRIMARY KEY (report_case_id, page_element_id),
|
|
351
|
+
CONSTRAINT fk_report_case_page_elements_case
|
|
352
|
+
FOREIGN KEY (report_case_id) REFERENCES report_cases(report_case_id)
|
|
353
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
354
|
+
CONSTRAINT fk_report_case_page_elements_element
|
|
355
|
+
FOREIGN KEY (page_element_id) REFERENCES page_elements(page_element_id)
|
|
356
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT
|
|
357
|
+
) STRICT;
|
|
358
|
+
|
|
359
|
+
CREATE TABLE reply_page_elements (
|
|
360
|
+
reply_id TEXT NOT NULL,
|
|
361
|
+
page_element_id TEXT NOT NULL,
|
|
362
|
+
CONSTRAINT pk_reply_page_elements PRIMARY KEY (reply_id, page_element_id),
|
|
363
|
+
CONSTRAINT fk_reply_page_elements_reply
|
|
364
|
+
FOREIGN KEY (reply_id) REFERENCES replies(reply_id)
|
|
365
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT,
|
|
366
|
+
CONSTRAINT fk_reply_page_elements_element
|
|
367
|
+
FOREIGN KEY (page_element_id) REFERENCES page_elements(page_element_id)
|
|
368
|
+
ON UPDATE RESTRICT ON DELETE RESTRICT
|
|
369
|
+
) STRICT;
|
|
370
|
+
|
|
371
|
+
CREATE TABLE "local_credentials" (
|
|
372
|
+
user_id TEXT PRIMARY KEY
|
|
373
|
+
, login_id TEXT COLLATE NOCASE NOT NULL
|
|
374
|
+
, email TEXT NOT NULL
|
|
375
|
+
, password_hash TEXT NOT NULL
|
|
376
|
+
, failed_login_count INTEGER NOT NULL DEFAULT 0
|
|
377
|
+
, locked_until TEXT
|
|
378
|
+
, email_verified_at TEXT
|
|
379
|
+
, password_changed_at TEXT NOT NULL
|
|
380
|
+
, last_login_at TEXT
|
|
381
|
+
, lock_version INTEGER NOT NULL DEFAULT 0
|
|
382
|
+
, created_at TEXT NOT NULL
|
|
383
|
+
, updated_at TEXT NOT NULL
|
|
384
|
+
, CONSTRAINT fk_local_credentials_user FOREIGN KEY (user_id)
|
|
385
|
+
REFERENCES users (user_id) ON DELETE RESTRICT
|
|
386
|
+
, CHECK (login_id = trim(login_id) AND length(login_id) BETWEEN 4 AND 50)
|
|
387
|
+
, CHECK (substr(login_id, 1, 1) GLOB '[A-Za-z0-9]')
|
|
388
|
+
, CHECK (login_id NOT GLOB '*[^A-Za-z0-9._-]*')
|
|
389
|
+
, CHECK (email = trim(email) AND length(email) BETWEEN 3 AND 320)
|
|
390
|
+
, CHECK (password_hash = trim(password_hash) AND length(password_hash) BETWEEN 20 AND 512)
|
|
391
|
+
, CHECK (failed_login_count >= 0)
|
|
392
|
+
, CHECK (lock_version >= 0)
|
|
393
|
+
) STRICT;
|
|
394
|
+
|
|
395
|
+
-- 최종 인덱스: UNIQUE 및 SqlGuid 표현식 정렬을 포함합니다.
|
|
396
|
+
CREATE INDEX ix_auth_refresh_tokens_user_active
|
|
397
|
+
ON auth_refresh_tokens (user_id, expires_at, refresh_token_id)
|
|
398
|
+
WHERE revoked_at IS NULL;
|
|
399
|
+
|
|
400
|
+
CREATE INDEX ix_project_members_user_joined_at
|
|
401
|
+
ON project_members (user_id, joined_at DESC, project_id DESC);
|
|
402
|
+
|
|
403
|
+
CREATE INDEX ix_project_members_project_role
|
|
404
|
+
ON project_members (project_id, role_code, user_id);
|
|
405
|
+
|
|
406
|
+
CREATE UNIQUE INDEX uq_feedbacks_project_environment_report_id
|
|
407
|
+
ON feedbacks (project_id, environment, report_id);
|
|
408
|
+
|
|
409
|
+
CREATE INDEX ix_feedbacks_assignee_status
|
|
410
|
+
ON feedbacks (assignee_id, status_code, updated_at DESC, feedback_id DESC);
|
|
411
|
+
|
|
412
|
+
CREATE INDEX ix_report_cases_assignee_status
|
|
413
|
+
ON report_cases (assignee_id, status_code, updated_at DESC, report_case_id DESC);
|
|
414
|
+
|
|
415
|
+
CREATE INDEX ix_replies_parent
|
|
416
|
+
ON replies (parent_reply_id, created_at, reply_id);
|
|
417
|
+
|
|
418
|
+
CREATE INDEX ix_report_case_page_elements_element
|
|
419
|
+
ON report_case_page_elements (page_element_id, report_case_id);
|
|
420
|
+
|
|
421
|
+
CREATE INDEX ix_reply_page_elements_element
|
|
422
|
+
ON reply_page_elements (page_element_id, reply_id);
|
|
423
|
+
|
|
424
|
+
CREATE UNIQUE INDEX uq_local_credentials_login_id ON local_credentials (login_id);
|
|
425
|
+
|
|
426
|
+
CREATE UNIQUE INDEX uq_local_credentials_email ON local_credentials (email);
|
|
427
|
+
|
|
428
|
+
CREATE INDEX ix_projects_status_created_at ON projects (status_code, created_at DESC, (substr(project_id, 25, 12) || substr(project_id, 20, 4) || substr(project_id, 17, 2) || substr(project_id, 15, 2) || substr(project_id, 12, 2) || substr(project_id, 10, 2) || substr(project_id, 7, 2) || substr(project_id, 5, 2) || substr(project_id, 3, 2) || substr(project_id, 1, 2)) DESC);
|
|
429
|
+
|
|
430
|
+
CREATE INDEX ix_projects_creator_created_at ON projects (creator_id, created_at DESC, (substr(project_id, 25, 12) || substr(project_id, 20, 4) || substr(project_id, 17, 2) || substr(project_id, 15, 2) || substr(project_id, 12, 2) || substr(project_id, 10, 2) || substr(project_id, 7, 2) || substr(project_id, 5, 2) || substr(project_id, 3, 2) || substr(project_id, 1, 2)) DESC);
|
|
431
|
+
|
|
432
|
+
CREATE INDEX ix_project_members_project_joined_at ON project_members (project_id, joined_at, (substr(user_id, 25, 12) || substr(user_id, 20, 4) || substr(user_id, 17, 2) || substr(user_id, 15, 2) || substr(user_id, 12, 2) || substr(user_id, 10, 2) || substr(user_id, 7, 2) || substr(user_id, 5, 2) || substr(user_id, 3, 2) || substr(user_id, 1, 2)));
|
|
433
|
+
|
|
434
|
+
CREATE INDEX ix_feedbacks_markers ON feedbacks (project_id, environment, pathname_hash, status_code, created_at DESC, (substr(feedback_id, 25, 12) || substr(feedback_id, 20, 4) || substr(feedback_id, 17, 2) || substr(feedback_id, 15, 2) || substr(feedback_id, 12, 2) || substr(feedback_id, 10, 2) || substr(feedback_id, 7, 2) || substr(feedback_id, 5, 2) || substr(feedback_id, 3, 2) || substr(feedback_id, 1, 2)) DESC);
|
|
435
|
+
|
|
436
|
+
CREATE INDEX ix_feedbacks_author_created_at ON feedbacks (author_id, created_at DESC, (substr(feedback_id, 25, 12) || substr(feedback_id, 20, 4) || substr(feedback_id, 17, 2) || substr(feedback_id, 15, 2) || substr(feedback_id, 12, 2) || substr(feedback_id, 10, 2) || substr(feedback_id, 7, 2) || substr(feedback_id, 5, 2) || substr(feedback_id, 3, 2) || substr(feedback_id, 1, 2)) DESC);
|
|
437
|
+
|
|
438
|
+
CREATE INDEX ix_report_cases_feedback_status_created_at ON report_cases (feedback_id, status_code, created_at DESC, (substr(report_case_id, 25, 12) || substr(report_case_id, 20, 4) || substr(report_case_id, 17, 2) || substr(report_case_id, 15, 2) || substr(report_case_id, 12, 2) || substr(report_case_id, 10, 2) || substr(report_case_id, 7, 2) || substr(report_case_id, 5, 2) || substr(report_case_id, 3, 2) || substr(report_case_id, 1, 2)) DESC);
|
|
439
|
+
|
|
440
|
+
CREATE INDEX ix_replies_report_case_created_at ON replies (report_case_id, created_at, (substr(reply_id, 25, 12) || substr(reply_id, 20, 4) || substr(reply_id, 17, 2) || substr(reply_id, 15, 2) || substr(reply_id, 12, 2) || substr(reply_id, 10, 2) || substr(reply_id, 7, 2) || substr(reply_id, 5, 2) || substr(reply_id, 3, 2) || substr(reply_id, 1, 2)));
|
|
441
|
+
|
|
442
|
+
CREATE INDEX ix_users_status_user_name ON users (status_code, user_name, (substr(user_id, 25, 12) || substr(user_id, 20, 4) || substr(user_id, 17, 2) || substr(user_id, 15, 2) || substr(user_id, 12, 2) || substr(user_id, 10, 2) || substr(user_id, 7, 2) || substr(user_id, 5, 2) || substr(user_id, 3, 2) || substr(user_id, 1, 2)));
|
|
443
|
+
|
|
444
|
+
CREATE INDEX ix_feedbacks_path_created_at ON feedbacks (project_id, environment, pathname_hash, created_at DESC, (substr(feedback_id, 25, 12) || substr(feedback_id, 20, 4) || substr(feedback_id, 17, 2) || substr(feedback_id, 15, 2) || substr(feedback_id, 12, 2) || substr(feedback_id, 10, 2) || substr(feedback_id, 7, 2) || substr(feedback_id, 5, 2) || substr(feedback_id, 3, 2) || substr(feedback_id, 1, 2)) DESC);
|
|
445
|
+
|
|
446
|
+
CREATE INDEX ix_report_cases_feedback_created_at ON report_cases (feedback_id, created_at DESC, (substr(report_case_id, 25, 12) || substr(report_case_id, 20, 4) || substr(report_case_id, 17, 2) || substr(report_case_id, 15, 2) || substr(report_case_id, 12, 2) || substr(report_case_id, 10, 2) || substr(report_case_id, 7, 2) || substr(report_case_id, 5, 2) || substr(report_case_id, 3, 2) || substr(report_case_id, 1, 2)) DESC);
|
|
447
|
+
|
|
448
|
+
-- 마지막 프로젝트 OWNER를 삭제/강등/교체하지 못하도록 보호하는 업무 트리거입니다.
|
|
449
|
+
CREATE TRIGGER tr_project_members_keep_owner_on_update
|
|
450
|
+
BEFORE UPDATE OF project_id, role_code ON project_members
|
|
451
|
+
FOR EACH ROW
|
|
452
|
+
WHEN OLD.role_code = 1
|
|
453
|
+
AND (NEW.project_id <> OLD.project_id OR NEW.role_code <> 1)
|
|
454
|
+
AND (
|
|
455
|
+
SELECT COUNT(*)
|
|
456
|
+
FROM project_members
|
|
457
|
+
WHERE project_id = OLD.project_id
|
|
458
|
+
AND role_code = 1
|
|
459
|
+
) <= 1
|
|
460
|
+
BEGIN
|
|
461
|
+
SELECT RAISE(ABORT, 'project-owner-required');
|
|
462
|
+
END;
|
|
463
|
+
|
|
464
|
+
CREATE TRIGGER tr_project_members_keep_owner_on_replace
|
|
465
|
+
BEFORE INSERT ON project_members
|
|
466
|
+
FOR EACH ROW
|
|
467
|
+
WHEN NEW.role_code <> 1
|
|
468
|
+
AND EXISTS (
|
|
469
|
+
SELECT 1
|
|
470
|
+
FROM project_members
|
|
471
|
+
WHERE project_id = NEW.project_id
|
|
472
|
+
AND user_id = NEW.user_id
|
|
473
|
+
AND role_code = 1
|
|
474
|
+
)
|
|
475
|
+
AND (
|
|
476
|
+
SELECT COUNT(*)
|
|
477
|
+
FROM project_members
|
|
478
|
+
WHERE project_id = NEW.project_id
|
|
479
|
+
AND role_code = 1
|
|
480
|
+
) <= 1
|
|
481
|
+
BEGIN
|
|
482
|
+
SELECT RAISE(ABORT, 'project-owner-required');
|
|
483
|
+
END;
|
|
484
|
+
|
|
485
|
+
CREATE TRIGGER tr_project_members_keep_owner_on_delete
|
|
486
|
+
BEFORE DELETE ON project_members
|
|
487
|
+
FOR EACH ROW
|
|
488
|
+
WHEN OLD.role_code = 1
|
|
489
|
+
AND (
|
|
490
|
+
SELECT COUNT(*)
|
|
491
|
+
FROM project_members
|
|
492
|
+
WHERE project_id = OLD.project_id
|
|
493
|
+
AND role_code = 1
|
|
494
|
+
) <= 1
|
|
495
|
+
BEGIN
|
|
496
|
+
SELECT RAISE(ABORT, 'project-owner-required');
|
|
497
|
+
END;
|
|
498
|
+
|
|
499
|
+
-- 최종 구조가 001~007 적용 결과와 같으므로 해당 이력도 같은 트랜잭션으로 등록합니다.
|
|
500
|
+
-- checksum은 원본 migration SQL 바이트의 SHA-256입니다. 임의 변경하지 마십시오.
|
|
501
|
+
INSERT INTO schema_migrations (version, name, checksum, applied_at) VALUES
|
|
502
|
+
(1, 'schema_migrations', '4b87d3d340de3ccf5fc49c58af4ee77c9b97829f63b5d6738f62536e1ff5511e', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
503
|
+
(2, 'identity', 'b3a254a2dbfcd45c45639e09bf7a7a20b299d23ec0ce625454a49a30c3a7f187', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
504
|
+
(3, 'projects', 'e43e59cef1429089ab64145712d225e681955d63ed0b48b433f452730d12c62e', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
505
|
+
(4, 'feedback_core', '7f3d6fabd427094438e05103f6137f6553a76ff0f8ed1a8ce41c38e708d764af', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
506
|
+
(5, 'project_member_management', 'b962aecbe7e5b8fbced8fcc756048832f44e465eafc1724528087f68cf0657e9', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
507
|
+
(6, 'align_credentials', '9219ee1d2355a21dff10089e20ccb1a746562a8d23dd669be6a53c4bd5edfc5b', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')),
|
|
508
|
+
(7, 'align_storage_values', '593cc57d8563707b1755a92173db44957c45765d36c4d2f60f3f9373effed367', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'));
|
|
509
|
+
|
|
510
|
+
INSERT INTO temp.fivepixels_init_guard (step) VALUES ('verify');
|
|
511
|
+
DROP TABLE temp.fivepixels_init_guard;
|
|
512
|
+
|
|
513
|
+
COMMIT;
|
|
514
|
+
|
|
515
|
+
-- 성공 확인: schema_version=7, integrity_check=ok, foreign_key_check 결과 없음.
|
|
516
|
+
SELECT MAX(version) AS schema_version FROM schema_migrations;
|
|
517
|
+
PRAGMA integrity_check;
|
|
518
|
+
PRAGMA foreign_key_check;
|