Merge pull request 'feat(patient):Implement repository and docker-compose' (#275) from feature/repository-setup into develop

Reviewed-on: ebhomengo/niki#275
Reviewed-by: hossein <h.nazari1990@gmail.com>
This commit is contained in:
hossein 2026-04-15 05:13:32 +00:00
commit 356a829c97
14 changed files with 957 additions and 93 deletions

View File

@ -3,17 +3,17 @@ package patientapp
import ( import (
"git.gocasts.ir/ebhomengo/niki/patientapp/config" "git.gocasts.ir/ebhomengo/niki/patientapp/config"
"git.gocasts.ir/ebhomengo/niki/patientapp/delivery/http/analytic" "git.gocasts.ir/ebhomengo/niki/patientapp/delivery/http/analytic"
"git.gocasts.ir/ebhomengo/niki/patientapp/repository/mysql" "git.gocasts.ir/ebhomengo/niki/repository/mysql"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
type Application struct { type Application struct {
//Config Config //Config Config
HTTPServer *config.EchoServer HTTPServer *config.EchoServer
DB *mysql.DataBase DB *mysql.DB
} }
func Setup(cfg config.Config, conn *mysql.DataBase) Application { func Setup(cfg config.Config, db *mysql.DB) Application {
e := echo.New() e := echo.New()
@ -25,13 +25,13 @@ func Setup(cfg config.Config, conn *mysql.DataBase) Application {
return Application{ return Application{
//Config: config, //Config: config,
HTTPServer: &server, HTTPServer: &server,
DB: conn, DB: db,
} }
} }
func (a Application) Start() { func (a Application) Start() {
server := analytic.NewServer(a.HTTPServer) server := analytic.NewServer(a.HTTPServer, a.DB)
_ = server.Serve() _ = server.Serve()
} }

View File

@ -1,15 +1,26 @@
package main package main
import ( import (
"os"
"strconv"
"time" "time"
"git.gocasts.ir/ebhomengo/niki/patientapp" "git.gocasts.ir/ebhomengo/niki/patientapp"
"git.gocasts.ir/ebhomengo/niki/patientapp/config" "git.gocasts.ir/ebhomengo/niki/patientapp/config"
"git.gocasts.ir/ebhomengo/niki/patientapp/repository/mysql" "git.gocasts.ir/ebhomengo/niki/repository/mysql"
) )
func main() { func main() {
db := mysql.DataBase{} dbConf := mysql.Config{
Username: os.Getenv("DB_USER"),
Password: os.Getenv("DB_PASS"),
Host: os.Getenv("DB_HOST"),
DBName: os.Getenv("DB_NAME"),
}
port, _ := strconv.Atoi(os.Getenv("DB_PORT"))
dbConf.Port = port
db := mysql.New(dbConf)
cfg := config.Config{ cfg := config.Config{
Port: 8080, Port: 8080,
@ -19,7 +30,7 @@ func main() {
ShutDownCtxTimeout: 5 * time.Second, ShutDownCtxTimeout: 5 * time.Second,
} }
app := patientapp.Setup(cfg, &db) app := patientapp.Setup(cfg, db)
app.Start() app.Start()

View File

@ -1,15 +1,15 @@
package analytic package analytic
import ( import (
"git.gocasts.ir/ebhomengo/niki/patientapp/repository/mysql" repo "git.gocasts.ir/ebhomengo/niki/patientapp/repository/mysql"
analytic2 "git.gocasts.ir/ebhomengo/niki/patientapp/service/analytic" analytic2 "git.gocasts.ir/ebhomengo/niki/patientapp/service/analytic"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
func NewPatientAnalyticRouter(s *echo.Group) { func NewPatientAnalyticRouter(s *echo.Group, db *mysql.DB) {
mysqlRepo := mysql.NewPatientRepo() mysqlRepo := repo.NewPatientRepo(db)
//rpcRepo := grpc.NewPatientRepo()
analyticService := analytic2.NewPatientAnalyticService(mysqlRepo) analyticService := analytic2.NewPatientAnalyticService(mysqlRepo)

View File

@ -5,16 +5,19 @@ import (
"fmt" "fmt"
"git.gocasts.ir/ebhomengo/niki/patientapp/config" "git.gocasts.ir/ebhomengo/niki/patientapp/config"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
) )
type Server struct { type Server struct {
HTTPServer *config.EchoServer HTTPServer *config.EchoServer
Db *mysql.DB
} }
func NewServer(server *config.EchoServer) *Server { func NewServer(server *config.EchoServer, db *mysql.DB) *Server {
return &Server{ return &Server{
HTTPServer: server, HTTPServer: server,
Db: db,
} }
} }
@ -35,7 +38,7 @@ func (s Server) RegisterRoutes() {
{ {
// Analytic Group // Analytic Group
analyticGroup := v1.Group("/analytic") analyticGroup := v1.Group("/analytic")
NewPatientAnalyticRouter(analyticGroup) NewPatientAnalyticRouter(analyticGroup, s.Db)
} }
} }

View File

@ -0,0 +1,32 @@
version: "3.9"
services:
mysql:
image: mysql:8.0
container_name: patient
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: patient
MYSQL_USER: appuser
MYSQL_PASSWORD: apppass
TZ: Asia/Tehran
command: [
"--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci",
"--default-authentication-plugin=mysql_native_password"
]
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./repository/migration:/docker-entrypoint-initdb.d
networks:
- backend
volumes:
mysql_data:
networks:
backend:
driver: bridge

View File

@ -0,0 +1,481 @@
-- MySQL dump 10.13 Distrib 8.0.29, for Linux (x86_64)
--
-- Host: localhost Database: patient
-- ------------------------------------------------------
-- Server version 8.0.29
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `audits`
--
DROP TABLE IF EXISTS `audits`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `audits` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_type` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`user_id` bigint unsigned DEFAULT NULL,
`event` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`auditable_type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`auditable_id` bigint unsigned NOT NULL,
`old_values` text COLLATE utf8mb4_unicode_ci,
`new_values` text COLLATE utf8mb4_unicode_ci,
`url` text COLLATE utf8mb4_unicode_ci,
`ip_address` varchar(45) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`user_agent` varchar(1023) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`tags` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `audits_auditable_type_auditable_id_index` (`auditable_type`,`auditable_id`),
KEY `audits_user_id_user_type_index` (`user_id`,`user_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `bandage_user`
--
DROP TABLE IF EXISTS `bandage_user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `bandage_user` (
`user_id` bigint unsigned NOT NULL,
`bandage_id` bigint unsigned NOT NULL,
`qty` int unsigned NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `bandages`
--
DROP TABLE IF EXISTS `bandages`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `bandages` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `cities`
--
DROP TABLE IF EXISTS `cities`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `cities` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`state_id` int unsigned NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=445 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `drug_user`
--
DROP TABLE IF EXISTS `drug_user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `drug_user` (
`user_id` bigint unsigned NOT NULL,
`drug_id` bigint unsigned NOT NULL,
`qty` int unsigned NOT NULL DEFAULT '0',
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `drugs`
--
DROP TABLE IF EXISTS `drugs`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `drugs` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `failed_jobs`
--
DROP TABLE IF EXISTS `failed_jobs`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `failed_jobs` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`connection` text COLLATE utf8mb4_unicode_ci NOT NULL,
`queue` text COLLATE utf8mb4_unicode_ci NOT NULL,
`payload` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`exception` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`failed_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `failed_jobs_uuid_unique` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `logs`
--
DROP TABLE IF EXISTS `logs`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `logs` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_id` int unsigned NOT NULL,
`type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`log` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20739 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `migrations`
--
DROP TABLE IF EXISTS `migrations`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `migrations` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`migration` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`batch` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `model_has_permissions`
--
DROP TABLE IF EXISTS `model_has_permissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `model_has_permissions` (
`permission_id` bigint unsigned NOT NULL,
`model_type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`model_id` bigint unsigned NOT NULL,
PRIMARY KEY (`permission_id`,`model_id`,`model_type`),
KEY `model_has_permissions_model_id_model_type_index` (`model_id`,`model_type`),
CONSTRAINT `model_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `model_has_roles`
--
DROP TABLE IF EXISTS `model_has_roles`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `model_has_roles` (
`role_id` bigint unsigned NOT NULL,
`model_type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`model_id` bigint unsigned NOT NULL,
PRIMARY KEY (`role_id`,`model_id`,`model_type`),
KEY `model_has_roles_model_id_model_type_index` (`model_id`,`model_type`),
CONSTRAINT `model_has_roles_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `password_resets`
--
DROP TABLE IF EXISTS `password_resets`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `password_resets` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint DEFAULT NULL,
`time` int DEFAULT NULL,
`token` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=227 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `permissions`
--
DROP TABLE IF EXISTS `permissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `permissions` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`guard_name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `reports`
--
DROP TABLE IF EXISTS `reports`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `reports` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint unsigned NOT NULL,
`agent_id` bigint unsigned NOT NULL,
`type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`interviewee` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`interviewee_name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`interviewee_ratio` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`content` text COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `reports_user_id_foreign` (`user_id`),
CONSTRAINT `reports_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=19846 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `role_has_permissions`
--
DROP TABLE IF EXISTS `role_has_permissions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `role_has_permissions` (
`permission_id` bigint unsigned NOT NULL,
`role_id` bigint unsigned NOT NULL,
PRIMARY KEY (`permission_id`,`role_id`),
KEY `role_has_permissions_role_id_foreign` (`role_id`),
CONSTRAINT `role_has_permissions_permission_id_foreign` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON DELETE CASCADE,
CONSTRAINT `role_has_permissions_role_id_foreign` FOREIGN KEY (`role_id`) REFERENCES `roles` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `roles`
--
DROP TABLE IF EXISTS `roles`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `roles` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`guard_name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `states`
--
DROP TABLE IF EXISTS `states`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `states` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `user_files`
--
DROP TABLE IF EXISTS `user_files`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_files` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint unsigned NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`type` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`label` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`status` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`message` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=40633 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `user_metas`
--
DROP TABLE IF EXISTS `user_metas`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_metas` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint unsigned NOT NULL,
`birthPlaceState` smallint unsigned NOT NULL DEFAULT '0',
`birthPlaceCity` smallint unsigned NOT NULL DEFAULT '0',
`religion` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`atba` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`nationality` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`atba_birthPlaceState` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`atba_birthPlaceCity` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`height` smallint unsigned DEFAULT NULL,
`weight` smallint unsigned DEFAULT NULL,
`eyeColor` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`bloodType` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`addressState` smallint unsigned NOT NULL,
`addressCity` smallint unsigned NOT NULL,
`address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`postalCode` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`phone` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`mobile` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`fMobile` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mMobile` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`ePhoneName` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`ePhoneNumber` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`houseType` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`housePrice` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`houseMortgage` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`houseRent` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`fAlive` tinyint(1) DEFAULT NULL,
`divorced` tinyint(1) NOT NULL DEFAULT '0',
`devorced` tinyint NOT NULL DEFAULT '0',
`fName` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`fBirthDate` date DEFAULT NULL,
`fNationalCode` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`fAtba` tinyint(1) NOT NULL DEFAULT '0',
`fNationality` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`fJob` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`fEdu` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mAlive` tinyint(1) DEFAULT NULL,
`mName` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mBirthDate` date DEFAULT NULL,
`mNationalCode` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mAtba` tinyint(1) NOT NULL DEFAULT '0',
`mNationality` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mJob` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`mEdu` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`ratio` tinyint(1) DEFAULT NULL,
`ratioType` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`liveChild` tinyint unsigned NOT NULL,
`ebChild` tinyint unsigned NOT NULL,
`Edu` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`skills` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`insurance` tinyint(1) NOT NULL,
`insuranceYear` tinyint unsigned DEFAULT NULL,
`insuranceMonth` tinyint unsigned DEFAULT NULL,
`insuranceCoverage` tinyint(1) NOT NULL,
`insuranceCoverageNumber` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`insuranceCoveragBranch` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`insuranceCoverageType` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`supplementaryInsurance` tinyint(1) NOT NULL,
`supplementaryInsuranceName` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`supportOrganization` tinyint(1) NOT NULL,
`supportOrganizationName` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`dailyProblemType` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` varchar(500) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`spouseName` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`spouseBirthDate` date DEFAULT NULL,
`spouseNationalCode` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`spouseAtba` tinyint(1) NOT NULL DEFAULT '0',
`spouseNationality` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`spouseJob` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`spouseEdu` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`spouseMobile` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`spouseAlive` tinyint(1) DEFAULT NULL,
`shenasname` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`shenasnamePlace` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `user_metas_user_id_foreign` (`user_id`),
CONSTRAINT `user_metas_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=1461 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `users`
--
DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`last_name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`username` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`pic` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`birth_date` date DEFAULT NULL,
`gender` tinyint(1) NOT NULL,
`marital` smallint unsigned DEFAULT NULL,
`deceased` date DEFAULT NULL,
`seyyed` tinyint(1) NOT NULL DEFAULT '0',
`profile_number` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`sheba` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`bank_account` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`bank_account_name` varchar(90) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`profile_status` tinyint unsigned DEFAULT NULL,
`medical_information_status` tinyint unsigned DEFAULT NULL,
`remember_token` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
`drug_description` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`bandage_description` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`bandage_period` tinyint unsigned DEFAULT NULL,
`bandage_months` text COLLATE utf8mb4_unicode_ci,
`twoFA_enabled` tinyint(1) NOT NULL DEFAULT '0',
`twoFA_secret` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`is_active` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
UNIQUE KEY `users_username_unique` (`username`),
KEY `users_twofa_enabled_index` (`twoFA_enabled`),
KEY `users_is_active_index` (`is_active`)
) ENGINE=InnoDB AUTO_INCREMENT=1918 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2026-04-14 7:28:21

View File

@ -1,35 +0,0 @@
package grpc
import (
"context"
"git.gocasts.ir/ebhomengo/niki/patientapp/service/analytic"
"git.gocasts.ir/ebhomengo/niki/patientapp/service/entity"
)
type AnalyticRepository struct{}
func NewPatientRepo() *AnalyticRepository {
return &AnalyticRepository{}
}
func (db *AnalyticRepository) GetPatients(ctx context.Context, f analytic.PatientFilter) ([]entity.Patient, error) {
return nil, nil
}
func (db *AnalyticRepository) CountPatients(ctx context.Context, f analytic.PatientFilter) (int, error) {
return 0, nil
}
func (db *AnalyticRepository) SummaryByCity(ctx context.Context, provinceID uint, f analytic.PatientMapFilter) (map[uint][]entity.MapSummaryItem, error) {
return nil, nil
}
func (db *AnalyticRepository) SummaryByProvince(ctx context.Context, f analytic.PatientMapFilter) (map[uint][]entity.MapSummaryItem, error) {
return nil, nil
}

View File

@ -2,35 +2,385 @@ package mysql
import ( import (
"context" "context"
"fmt"
"git.gocasts.ir/ebhomengo/niki/patientapp/service/analytic" "git.gocasts.ir/ebhomengo/niki/patientapp/service/analytic"
"git.gocasts.ir/ebhomengo/niki/patientapp/service/entity" "git.gocasts.ir/ebhomengo/niki/patientapp/service/entity"
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
) )
type DataBase struct{} type DataBase struct {
conn *mysql.DB
func NewPatientRepo() *DataBase {
return &DataBase{}
} }
func (db *DataBase) GetPatients(ctx context.Context, f analytic.PatientFilter) ([]entity.Patient, error) { func NewPatientRepo(db *mysql.DB) *DataBase {
return nil, nil return &DataBase{
conn: db,
}
}
func (db *DataBase) GetPatients(ctx context.Context, f analytic.PatientFilter) ([]entity.UserMeta, error) {
const Op = "repository.mysql.patient.get"
tx, err := db.conn.Conn().BeginTx(ctx, nil)
if err != nil {
return []entity.UserMeta{}, richerror.New(Op).WithErr(err)
}
defer tx.Rollback()
query := `
SELECT
um.id,
um.user_id,
u.birthDate,
u.sex,
um.birthPlaceState,
um.birthPlaceCity,
um.nationality,
um.addressState,
um.addressCity,
um.address,
um.phone,
um.mobile,
um.spouseName,
um.created_at,
um.updated_at
FROM user_metas um
JOIN users u ON u.id = um.user_id
WHERE 1=1
`
args := []any{}
// Birthdate filters (FROM = born after)
if f.DOBFrom != nil && *f.DOBFrom != "" {
query += " AND u.birth_date >= ?"
args = append(args, *f.DOBFrom)
}
if f.DOBTo != nil && *f.DOBTo != "" {
query += " AND u.birth_date <= ?"
args = append(args, *f.DOBTo)
}
// Sex
if f.Sex != nil && *f.Sex != "" {
query += " AND u.sex = ?"
args = append(args, *f.Sex)
}
// Nationality
if f.Nationality != "" {
query += " AND um.nationality = ?"
args = append(args, f.Nationality)
}
// Address
if f.AddressState != 0 {
query += " AND um.addressState = ?"
args = append(args, f.AddressState)
}
if f.AddressCity != 0 {
query += " AND um.addressCity = ?"
args = append(args, f.AddressCity)
}
// Search on fields from user_metas and users
if f.Search != nil && *f.Search != "" {
like := "%" + *f.Search + "%"
query += `
AND (
um.fName LIKE ? OR
um.mName LIKE ? OR
um.spouseName LIKE ? OR
um.phone LIKE ? OR
um.mobile LIKE ?
)
`
args = append(args, like, like, like, like, like)
}
query += " ORDER BY id DESC"
if f.Limit > 0 {
query += " LIMIT ?"
args = append(args, f.Limit)
}
if f.Offset > 0 {
query += " OFFSET ?"
args = append(args, f.Offset)
}
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
return nil, richerror.New(Op).WithErr(err)
}
defer rows.Close()
var result []entity.UserMeta
for rows.Next() {
var u entity.UserMeta
if err := rows.Scan(
&u.ID, &u.UserID, &u.BirthDate, &u.Gender, &u.BirthPlaceState, &u.BirthPlaceCity,
&u.Religion, &u.Nationality, &u.AddressState, &u.AddressCity,
&u.Address, &u.Mobile, &u.SpouseName, &u.SpouseAlive,
&u.CreatedAt, &u.UpdatedAt,
); err != nil {
return nil, richerror.New(Op).WithErr(err)
}
result = append(result, u)
}
if err := rows.Err(); err != nil {
return nil, richerror.New(Op).WithErr(err)
}
return result, nil
} }
func (db *DataBase) CountPatients(ctx context.Context, f analytic.PatientFilter) (int, error) { func (db *DataBase) CountPatients(ctx context.Context, f analytic.PatientFilter) (int, error) {
const Op = "repository.mysql.patient.count"
return 0, nil tx, err := db.conn.Conn().BeginTx(ctx, nil)
if err != nil {
return 0, richerror.New(Op).WithErr(err)
}
defer tx.Rollback()
query := `
SELECT COUNT(*)
FROM user_metas um
JOIN users u ON u.id = um.user_id
WHERE 1=1
`
args := []any{}
// Birthdate range
if f.DOBFrom != nil && *f.DOBFrom != "" {
query += " AND u.birth_date >= ?"
args = append(args, *f.DOBFrom)
}
if f.DOBTo != nil && *f.DOBTo != "" {
query += " AND u.birth_date <= ?"
args = append(args, *f.DOBTo)
}
// Sex
if f.Sex != nil && *f.Sex != "" {
query += " AND u.sex = ?"
args = append(args, *f.Sex)
}
// Nationality
if f.Nationality != "" {
query += " AND um.nationality = ?"
args = append(args, f.Nationality)
}
// Address
if f.AddressState != 0 {
query += " AND um.addressState = ?"
args = append(args, f.AddressState)
}
if f.AddressCity != 0 {
query += " AND um.addressCity = ?"
args = append(args, f.AddressCity)
}
// Search
if f.Search != nil && *f.Search != "" {
like := "%" + *f.Search + "%"
query += `
AND (
um.fName LIKE ? OR
um.mName LIKE ? OR
um.spouseName LIKE ? OR
um.phone LIKE ? OR
um.mobile LIKE ?
)
`
args = append(args, like, like, like, like, like)
}
var count int
err = tx.QueryRowContext(ctx, query, args...).Scan(&count)
if err != nil {
return 0, fmt.Errorf("%s: query error: %w", Op, err)
}
return count, nil
} }
func (db *DataBase) SummaryByCity(ctx context.Context, provinceID uint, f analytic.PatientMapFilter) (map[uint][]entity.MapSummaryItem, error) { func (db *DataBase) SummaryByCity(ctx context.Context, provinceID uint, f analytic.PatientMapFilter) (map[uint][]entity.MapSummaryItem, error) {
const Op = "repository.mysql.patient.map_summary"
return nil, nil tx, err := db.conn.Conn().BeginTx(ctx, nil)
if err != nil {
return nil, richerror.New(Op).WithErr(err)
}
defer tx.Rollback()
query := `
SELECT
um.addressCity AS city_id,
ANY_VALUE(um.lat) AS lat,
ANY_VALUE(um.lng) AS lng,
COUNT(*) AS user_count
FROM user_metas um
JOIN users u ON u.id = um.user_id
JOIN cities c ON c.id = um.addressCity
WHERE c.state_id = ?
`
args := []any{provinceID}
// Birthdate filters
if f.MinDOB != nil && *f.MinDOB != "" {
query += " AND u.birth_date >= ?"
args = append(args, *f.MinDOB)
}
if f.MaxDOB != nil && *f.MaxDOB != "" {
query += " AND u.birth_date <= ?"
args = append(args, *f.MaxDOB)
}
// Sex filter
if f.Sex != nil && *f.Sex != "" {
query += " AND u.sex = ?"
args = append(args, *f.Sex)
}
// Search filter
if f.Search != nil && *f.Search != "" {
like := "%" + *f.Search + "%"
query += `
AND (
um.fName LIKE ? OR
um.mName LIKE ? OR
um.spouseName LIKE ? OR
um.phone LIKE ? OR
um.mobile LIKE ?
)
`
args = append(args, like, like, like, like, like)
}
// Group by city
query += " GROUP BY um.addressCity"
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%s: query error: %w", Op, err)
}
defer rows.Close()
result := make(map[uint][]entity.MapSummaryItem)
for rows.Next() {
var item entity.MapSummaryItem
err := rows.Scan(
&item.ID,
&item.Latitude,
&item.Longitude,
&item.Count,
)
if err != nil {
return nil, fmt.Errorf("%s: scan error: %w", Op, err)
}
result[item.ID] = append(result[item.ID], item)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("%s: rows error: %w", Op, err)
}
return result, nil
} }
func (db *DataBase) SummaryByProvince(ctx context.Context, f analytic.PatientMapFilter) (map[uint][]entity.MapSummaryItem, error) { func (db *DataBase) SummaryByProvince(ctx context.Context, f analytic.PatientMapFilter) (map[uint][]entity.MapSummaryItem, error) {
return nil, nil const Op = "repository.mysql.patient.summary_by_province"
tx, err := db.conn.Conn().BeginTx(ctx, nil)
if err != nil {
return nil, richerror.New(Op).WithErr(err)
}
defer tx.Rollback()
query := `
SELECT
c.state_id,
ANY_VALUE(c.lat) AS lat,
ANY_VALUE(c.lng) AS lng,
COUNT(*) AS total
FROM user_metas um
JOIN users u ON u.id = um.user_id
JOIN cities c ON c.id = um.addressCity
WHERE 1 = 1
`
args := []any{}
// Birthdate filters
if f.MinDOB != nil && *f.MinDOB != "" {
query += " AND u.birth_date >= ?"
args = append(args, *f.MinDOB)
}
if f.MaxDOB != nil && *f.MaxDOB != "" {
query += " AND u.birth_date <= ?"
args = append(args, *f.MaxDOB)
}
// Sex filter
if f.Sex != nil && *f.Sex != "" {
query += " AND u.sex = ?"
args = append(args, *f.Sex)
}
// Search filter
if f.Search != nil && *f.Search != "" {
like := "%" + *f.Search + "%"
query += `
AND (
um.fName LIKE ? OR
um.mName LIKE ? OR
um.spouseName LIKE ? OR
um.phone LIKE ? OR
um.mobile LIKE ?
)
`
args = append(args, like, like, like, like, like)
}
query += " GROUP BY c.state_id"
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
return nil, fmt.Errorf("%s: query error: %w", Op, err)
}
defer rows.Close()
result := make(map[uint][]entity.MapSummaryItem)
for rows.Next() {
var item entity.MapSummaryItem
if err := rows.Scan(&item.ID, &item.Latitude, &item.Longitude, &item.Count); err != nil {
return nil, fmt.Errorf("%s: scan error: %w", Op, err)
}
result[item.ID] = []entity.MapSummaryItem{item}
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("%s: rows error: %w", Op, err)
}
return result, nil
} }

View File

@ -6,12 +6,12 @@ import (
type ListPatientAnalyticRequest struct { type ListPatientAnalyticRequest struct {
// All fields are optional // All fields are optional
MinAge *int `query:"minAge,omitempty"` MinAge *int `query:"minAge,omitempty"`
MaxAge *int `query:"maxAge,omitempty"` MaxAge *int `query:"maxAge,omitempty"`
Sex *entity.Sex `query:"sex,omitempty"` Sex *string `query:"sex,omitempty"`
City *int64 `query:"city,omitempty"` City *uint16 `query:"city,omitempty"`
Province *int64 `query:"province,omitempty"` Province *uint16 `query:"province,omitempty"`
Search *string `query:"search,omitempty"` Search *string `query:"search,omitempty"`
@ -19,11 +19,11 @@ type ListPatientAnalyticRequest struct {
} }
type PatientAnalyticItem struct { type PatientAnalyticItem struct {
ID int64 `json:"id"` ID uint64 `json:"id"`
FirstName string `json:"first_name"` FirstName string `json:"first_name"`
LastName string `json:"Last_name"` LastName string `json:"Last_name"`
DateOfBirth string `json:"dob,omitempty"` DateOfBirth string `json:"dob,omitempty"`
Sex entity.Sex `json:"sex"` Sex string `json:"sex"`
Phone string `json:"phone"` Phone string `json:"phone"`
Address entity.Address `json:"address"` Address entity.Address `json:"address"`
} }
@ -33,17 +33,17 @@ type PatientAnalyticResponse struct {
Total int `json:"total"` Total int `json:"total"`
} }
func ToPatientResponse(patient entity.Patient) PatientAnalyticItem { func ToPatientResponse(patient entity.UserMeta) PatientAnalyticItem {
return PatientAnalyticItem{ return PatientAnalyticItem{
ID: patient.ID, ID: patient.ID,
FirstName: patient.FirstName, FirstName: patient.Name,
LastName: patient.LastName, LastName: patient.LastName,
DateOfBirth: patient.DateOfBirth, DateOfBirth: patient.BirthDate,
Sex: patient.Sex, Sex: patient.Gender,
Phone: patient.Phone, Phone: *patient.Mobile,
Address: entity.Address{ Address: entity.Address{
ProvinceID: patient.Address.ProvinceID, ProvinceID: patient.AddressState,
CityID: patient.Address.CityID, CityID: patient.AddressCity,
}, },
} }
} }

View File

@ -7,11 +7,11 @@ import (
type PatientFilter struct { type PatientFilter struct {
DOBFrom *string // born after DOBFrom *string // born after
DOBTo *string // born before DOBTo *string // born before
Sex *entity.Sex Sex *string
City *int64 Nationality string
Province *int64 AddressState uint16
Country *int64 AddressCity uint16
Search *string Search *string

View File

@ -16,7 +16,7 @@ var (
) )
type Repository interface { type Repository interface {
GetPatients(ctx context.Context, f PatientFilter) ([]entity.Patient, error) GetPatients(ctx context.Context, f PatientFilter) ([]entity.UserMeta, error)
CountPatients(ctx context.Context, f PatientFilter) (int, error) CountPatients(ctx context.Context, f PatientFilter) (int, error)
SummaryByCity(ctx context.Context, provinceID uint, f PatientMapFilter) (map[uint][]entity.MapSummaryItem, error) SummaryByCity(ctx context.Context, provinceID uint, f PatientMapFilter) (map[uint][]entity.MapSummaryItem, error)
@ -41,14 +41,14 @@ func (s Service) List(ctx context.Context, req ListPatientAnalyticRequest) (Pati
dobFrom, dobTo := ageRangeToDOB(req.MinAge, req.MaxAge, time.Now()) dobFrom, dobTo := ageRangeToDOB(req.MinAge, req.MaxAge, time.Now())
filter := PatientFilter{ filter := PatientFilter{
DOBFrom: dobFrom, DOBFrom: dobFrom,
DOBTo: dobTo, DOBTo: dobTo,
Sex: req.Sex, Sex: req.Sex,
City: req.City, AddressCity: *req.City,
Province: req.Province, AddressState: *req.Province,
Search: req.Search, Search: req.Search,
Limit: limit, Limit: limit,
Offset: offset, Offset: offset,
} }
items, err := s.repository.GetPatients(ctx, filter) items, err := s.repository.GetPatients(ctx, filter)

View File

@ -7,8 +7,8 @@ type Address struct {
Name string Name string
Lat float64 Lat float64
Lon float64 Lon float64
CityID uint CityID uint16
ProvinceID uint ProvinceID uint16
} }
type AddressAggregated struct { type AddressAggregated struct {

View File

@ -9,9 +9,8 @@ const (
) )
type MapSummaryItem struct { type MapSummaryItem struct {
LocationID int64 ID uint `json:"id"` // city_id OR state_id
Name string Latitude float64 `json:"latitude"`
Count int Longitude float64 `json:"longitude"`
CentroidLat float64 Count int `json:"count"`
CentroidLng float64
} }

View File

@ -1,5 +1,7 @@
package entity package entity
import "time"
type Patient struct { type Patient struct {
ID int64 ID int64
FirstName string FirstName string
@ -15,6 +17,27 @@ type Patient struct {
EndDate string EndDate string
} }
type UserMeta struct {
ID uint64 `db:"id"`
UserID uint64 `db:"user_id"`
Name string `db:"name"`
LastName string `db:"last_name"`
Gender string `db:"gender"`
BirthDate string `db:"birth_date"`
BirthPlaceState uint16 `db:"birthPlaceState"`
BirthPlaceCity uint16 `db:"birthPlaceCity"`
Religion *string `db:"religion"`
Nationality *string `db:"nationality"`
AddressState uint16 `db:"addressState"`
AddressCity uint16 `db:"addressCity"`
Address string `db:"address"`
Mobile *string `db:"mobile"`
SpouseName *string `db:"spouseName"`
SpouseAlive *bool `db:"spouseAlive"`
CreatedAt *time.Time `db:"created_at"`
UpdatedAt *time.Time `db:"updated_at"`
}
// Sex ================================== Sex type ========================================== // Sex ================================== Sex type ==========================================
type Sex string type Sex string