feat: Configure database with Prisma and MySQL spatial support (Task 22)
- Set up MySQL 8.0+ with spatial data support (POINT SRID 4326) - Created Prisma schema with all models (User, Report, Event, etc.) - Added Clerk authentication support (clerk_id field) - Configured spatial indexes on location fields for performance - Created database migrations and applied to MySQL - Built spatial query utilities for geographical operations - Added database connection singleton and health checks - Created comprehensive documentation and test scripts Requirements: 1.1, 2.1, 3.2, 4.1
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `users` (
|
||||
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()),
|
||||
`clerk_id` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NOT NULL,
|
||||
`username` VARCHAR(100) NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`first_name` VARCHAR(100) NULL,
|
||||
`last_name` VARCHAR(100) NULL,
|
||||
`avatar_url` VARCHAR(500) NULL,
|
||||
`impact_score` INTEGER NULL DEFAULT 0,
|
||||
`notification_email` BOOLEAN NULL DEFAULT true,
|
||||
`notification_in_app` BOOLEAN NULL DEFAULT true,
|
||||
`areas_of_interest` JSON NULL,
|
||||
|
||||
UNIQUE INDEX `clerk_id`(`clerk_id`),
|
||||
UNIQUE INDEX `email`(`email`),
|
||||
UNIQUE INDEX `username`(`username`),
|
||||
INDEX `idx_clerk_id`(`clerk_id`),
|
||||
INDEX `idx_email`(`email`),
|
||||
INDEX `idx_username`(`username`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `reports` (
|
||||
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()),
|
||||
`user_id` VARCHAR(36) NOT NULL,
|
||||
`location` POINT NOT NULL SRID 4326,
|
||||
`latitude` DECIMAL(10, 8) NOT NULL,
|
||||
`longitude` DECIMAL(11, 8) NOT NULL,
|
||||
`location_source` ENUM('exif', 'gps', 'manual') NOT NULL,
|
||||
`photo_urls` JSON NOT NULL,
|
||||
`photo_timestamp` TIMESTAMP(0) NULL,
|
||||
`litter_type` ENUM('plastic', 'metal', 'glass', 'organic', 'hazardous', 'other') NOT NULL,
|
||||
`quantity` ENUM('minimal', 'moderate', 'significant', 'severe') NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`submitted_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`verification_status` ENUM('pending', 'verified', 'disputed') NULL DEFAULT 'pending',
|
||||
|
||||
INDEX `idx_created_at`(`created_at`),
|
||||
INDEX `idx_lat_lng`(`latitude`, `longitude`),
|
||||
INDEX `idx_litter_type`(`litter_type`),
|
||||
SPATIAL INDEX `idx_location`(`location`),
|
||||
INDEX `user_id`(`user_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `events` (
|
||||
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()),
|
||||
`organizer_id` VARCHAR(36) NOT NULL,
|
||||
`title` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NOT NULL,
|
||||
`location` POINT NOT NULL SRID 4326,
|
||||
`latitude` DECIMAL(10, 8) NOT NULL,
|
||||
`longitude` DECIMAL(11, 8) NOT NULL,
|
||||
`location_name` VARCHAR(255) NOT NULL,
|
||||
`scheduled_date` TIMESTAMP(0) NOT NULL,
|
||||
`duration` INTEGER NOT NULL COMMENT 'Duration in minutes',
|
||||
`status` ENUM('upcoming', 'completed', 'cancelled') NULL DEFAULT 'upcoming',
|
||||
`participant_count` INTEGER NULL DEFAULT 0,
|
||||
`litter_collected` DECIMAL(10, 2) NULL COMMENT 'Kilograms collected',
|
||||
`photos` JSON NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
|
||||
SPATIAL INDEX `idx_location`(`location`),
|
||||
INDEX `idx_scheduled_date`(`scheduled_date`),
|
||||
INDEX `idx_status`(`status`),
|
||||
INDEX `organizer_id`(`organizer_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `event_registrations` (
|
||||
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()),
|
||||
`user_id` VARCHAR(36) NOT NULL,
|
||||
`event_id` VARCHAR(36) NOT NULL,
|
||||
`registered_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`attended` BOOLEAN NULL DEFAULT false,
|
||||
|
||||
INDEX `event_id`(`event_id`),
|
||||
UNIQUE INDEX `unique_user_event`(`user_id`, `event_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `verifications` (
|
||||
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()),
|
||||
`report_id` VARCHAR(36) NOT NULL,
|
||||
`user_id` VARCHAR(36) NOT NULL,
|
||||
`verification_type` ENUM('verify', 'dispute') NOT NULL,
|
||||
`comment` TEXT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX `user_id`(`user_id`),
|
||||
UNIQUE INDEX `unique_report_user`(`report_id`, `user_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `environmental_concerns` (
|
||||
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()),
|
||||
`report_id` VARCHAR(36) NOT NULL,
|
||||
`concern_type` VARCHAR(100) NOT NULL COMMENT 'water_quality, erosion, wildlife_impact, algae_bloom, etc.',
|
||||
`severity` ENUM('low', 'medium', 'high', 'critical') NOT NULL,
|
||||
`description` TEXT NOT NULL,
|
||||
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
INDEX `idx_concern_type`(`concern_type`),
|
||||
INDEX `report_id`(`report_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `hotspots` (
|
||||
`id` VARCHAR(36) NOT NULL DEFAULT (UUID()),
|
||||
`location` POINT NOT NULL SRID 4326,
|
||||
`latitude` DECIMAL(10, 8) NOT NULL,
|
||||
`longitude` DECIMAL(11, 8) NOT NULL,
|
||||
`radius` DECIMAL(10, 2) NOT NULL COMMENT 'Radius in meters',
|
||||
`report_count` INTEGER NOT NULL,
|
||||
`severity_score` DECIMAL(5, 2) NOT NULL,
|
||||
`last_report_date` TIMESTAMP(0) NOT NULL,
|
||||
`calculated_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
SPATIAL INDEX `idx_location`(`location`),
|
||||
INDEX `idx_severity_score`(`severity_score`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE=InnoDB;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `reports` ADD CONSTRAINT `reports_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `events` ADD CONSTRAINT `events_ibfk_1` FOREIGN KEY (`organizer_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `event_registrations` ADD CONSTRAINT `event_registrations_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `event_registrations` ADD CONSTRAINT `event_registrations_ibfk_2` FOREIGN KEY (`event_id`) REFERENCES `events`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `verifications` ADD CONSTRAINT `verifications_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `reports`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `verifications` ADD CONSTRAINT `verifications_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `environmental_concerns` ADD CONSTRAINT `environmental_concerns_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `reports`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
Reference in New Issue
Block a user