Compare commits

..

123 Commits

Author SHA1 Message Date
hossein b9db2926c1 Merge pull request 'add-benefactor' (#220) from add-benefactor into develop
Reviewed-on: ebhomengo/niki#220
Reviewed-by: hossein <h.nazari1990@gmail.com>
2026-03-20 15:02:57 +00:00
mohammadreza javid 3771aae4d2 add structure of benefactorapp to niki project 2026-03-20 14:38:06 +03:30
mohammadreza javid fda7be1d7a update readme niki project 2026-03-20 13:51:12 +03:30
mohammadreza javid 8a1ee39221 update gitignore 2026-03-20 13:41:35 +03:30
mohammadreza javid 380de96b1f bug fix in migration 1730029129_add_update_benefactor_access.sql 2026-03-20 13:40:20 +03:30
mohammadreza javid 38cd7d1c1c update go version from 1.23 to 1.25.3 2026-03-20 13:38:26 +03:30
hossein 0b1d2e5bd3 Merge pull request 'feat(admin): add admin my profile route(#217)' (#218) from stage/hamed/my-profile into develop
Reviewed-on: ebhomengo/niki#218
2024-12-04 16:17:41 +00:00
Hamed Xamani b87f02db05 feat(admin): add admin my profile route(#217) 2024-12-03 18:53:21 +03:30
hossein 5359a0746f Merge pull request 'feat(admin): generate and store fake data(#215)' (#216) from stage/hamed/seed into develop
Reviewed-on: ebhomengo/niki#216
2024-12-01 13:50:38 +00:00
hossein b9631950c0 Merge branch 'develop' into stage/hamed/seed 2024-12-01 13:50:13 +00:00
hossein e7ea933038 Merge pull request 'refactor(admin): change aggregation response struct' (#214) from stage/hamed/change-agg-struck into develop
Reviewed-on: ebhomengo/niki#214
2024-12-01 13:50:00 +00:00
Hamed Xamani 84ef02d2ed feat(admin): generate and store fake data(#215) 2024-12-01 11:41:02 +03:30
Hamed Xamani 16c83e1368 refactor(admin): change aggregation response struct 2024-11-27 16:47:02 +03:30
hossein 7aa381c113 Merge pull request 'fix(admin): fix query total and refactor query search' (#213) from stage/hamed/refactor-search into develop
Reviewed-on: ebhomengo/niki#213
2024-11-27 05:21:40 +00:00
hossein 4ee7c48797 Merge branch 'develop' into stage/hamed/refactor-search 2024-11-27 05:21:21 +00:00
hossein 4e2baf17c9 Merge pull request 'feat(admin): append refer time key on get all kindbox' (#210) from stage/hamed/kind_box_aggreation into develop
Reviewed-on: ebhomengo/niki#210
2024-11-23 10:28:43 +00:00
Hamed Xamani 241272eb7b feat(admin): append refer time key on get all kindbox(#121) 2024-11-23 13:35:00 +03:30
Hamed Xamani dddd1125d0 fix(admin): fix query total and refactor query search 2024-11-20 11:26:59 +03:30
hossein a239bb089c Merge pull request 'feat(admin): append nested data in kindbox and kindboxreq(#208)' (#209) from stage/hamed/agregate-kindbox into develop
Reviewed-on: ebhomengo/niki#209
2024-11-19 15:51:32 +00:00
hossein 6a8005592d Merge branch 'develop' into stage/hamed/agregate-kindbox 2024-11-19 15:51:21 +00:00
hossein 54da7e48fa Merge pull request 'feat(admin): add benefactor aggregator service(#198)' (#207) from stage/hamed/agregate-service into develop
Reviewed-on: ebhomengo/niki#207
2024-11-19 15:51:12 +00:00
Hamed Xamani 4e97455049 feat(admin): append nested data in kindbox and kindboxreq(#208) 2024-11-19 10:15:20 +03:30
Hamed Xamani 1d14e86602 feat(admin): add benefactor aggregator service(#198) 2024-11-19 08:20:05 +03:30
hossein bf8a141f68 Merge pull request 'fix(niki): fix get all kindbox and kindboxreq with filter param' (#206) from stage/hamed/fix-get-all-api into develop
Reviewed-on: ebhomengo/niki#206
2024-11-10 19:46:14 +00:00
Hamed Xamani 61c943c0ac fix(niki): fix get all kindbox and kindboxreq with filter param 2024-11-09 20:09:47 +03:30
hossein 69d4a3ec2b Merge pull request 'Fix priority run migration admin_access' (#205) from stage/hamed/fix-migration into develop
Reviewed-on: ebhomengo/niki#205
2024-11-06 05:32:54 +00:00
hossein fa670eda35 Merge branch 'develop' into stage/hamed/fix-migration 2024-11-06 05:32:45 +00:00
hossein 84cc20c0ac Merge pull request 'refactor(niki): remove unnecessary id validation(#131)' (#202) from stage/hamed/unnecessary-check-userid into develop
Reviewed-on: ebhomengo/niki#202
2024-11-06 05:12:11 +00:00
hossein 7292ce6c09 Merge branch 'develop' into stage/hamed/unnecessary-check-userid 2024-11-06 05:11:59 +00:00
Hamed Xamani a7a90a118f Fix priority run migration admin_access 2024-11-05 17:29:55 +03:30
hossein 8407126700 Merge pull request 'feat(admin): implement update benefactor profile and change status(#196)' (#199) from stage/hamed/edit-benefactor into develop
Reviewed-on: ebhomengo/niki#199
2024-11-04 19:04:48 +00:00
hossein 67d9d5cb7d fix conflicts 2024-11-04 22:33:04 +03:30
hossein e13a517811 Merge pull request 'feat(admin): add search query param(#195)' (#201) from stage/hamed/add-search-param into develop
Reviewed-on: ebhomengo/niki#201
2024-11-04 18:57:09 +00:00
hossein 63ffcb8f92 Merge branch 'develop' into stage/hamed/add-search-param 2024-11-04 18:56:53 +00:00
hossein f52850c8d2 Merge pull request 'fix(niki): fix date zero values in response(#197)' (#203) from stage/hamed/null-time into develop
Reviewed-on: ebhomengo/niki#203
2024-11-04 18:56:19 +00:00
Hamed Xamani 86caf92026 fix(niki): fix date zero values in response(#197) 2024-11-04 20:03:29 +03:30
Hamed Xamani d4a768974a refactor(niki): remove unnecessary id validation(#131) 2024-11-04 17:44:15 +03:30
Hamed Xamani 07b7509a50 feat(admin): add search query param(#195)
add search on get all in benefactor, kindbox and kindboxreq endpoint
2024-11-04 15:12:22 +03:30
hossein e1fde10138 Merge pull request 'fix(niki): add benefactor_id filter to avoid getting all kindboxes' (#200) from stage/erfan/fix-get-benefactor into develop
Reviewed-on: ebhomengo/niki#200
2024-11-01 19:05:48 +00:00
Erfan Mohammadi 3dd67e0f83 fix(niki): add benefactor_id filter to avoid getting all kindboxes 2024-11-01 19:26:13 +03:30
Hamed Xamani f067686af7 feat(admin): implement update benefactor profile and change status(#196) 2024-10-29 15:04:12 +03:30
hossein 0e92213d2e Merge pull request 'feat(niki): get benefactor info by admin (#174)' (#192) from stage/ruhollahh01/get-benefactor-by-admin into develop
Reviewed-on: ebhomengo/niki#192
2024-10-29 11:06:35 +00:00
Ruhollah f1ad1b9051 feat(niki): get benefactor info by admin (#174) 2024-10-25 12:23:04 +03:30
hossein 3ac97bce91 Merge pull request 'feat(admin): Add status filter in get all refer times(#193)' (#194) from stage/hamed/add-refer-time-filter into develop
Reviewed-on: ebhomengo/niki#194
2024-10-23 05:30:42 +00:00
Hamed Xamani 281adb0af5 feat(admin): Add status filter in get all refer times(#193) 2024-10-21 14:32:25 +03:30
Erfan Mohammadi 300b69b449 feat(niki): get all benefactors by admin 2024-10-10 11:48:25 +03:30
AMiR 046b292f9f feat(niki): get all benefactor by admin 2024-10-10 11:35:42 +03:30
hossein cf27483182 Merge pull request 'feat(niki): add api to fetch refer time list for benefactor and admin' (#190) from stage/hamed/get-all-refer-time into develop
Reviewed-on: ebhomengo/niki#190
2024-10-09 05:21:28 +00:00
hossein e5119a1701 Merge branch 'develop' into stage/hamed/get-all-refer-time 2024-10-09 05:17:20 +00:00
hossein 845e321b7b Merge pull request 'fix(delivery): Remove unused filter from delivery to service layer (#165)' (#189) from stage/hamed/remove-filter-benefactor-id into develop
Reviewed-on: ebhomengo/niki#189
2024-10-09 05:16:27 +00:00
hossein 4d8f8adf59 Merge branch 'develop' into stage/hamed/remove-filter-benefactor-id 2024-10-09 05:16:16 +00:00
hossein 08ff2d3d40 Merge pull request 'Benefactor Tests: Address, Kind box requests, benefactor' (#149) from stage/rezoo/e2e-test/benefactor into develop
Reviewed-on: ebhomengo/niki#149
2024-10-09 05:13:07 +00:00
Reza Mobaraki dad8eba72d
update vendor
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-10-08 21:33:54 +03:30
Reza Mobaraki 606650e32b
test(end2end): update tests, remove mock data
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-10-08 21:33:04 +03:30
Hamed Xamani 78db09faf4 feat(niki): add api to fetch refer time list for benefactor and admin 2024-10-08 00:27:11 +03:30
Hamed Xamani 6f6643552d fix(delivery): remove unused filter from delivery to service layer (#165) 2024-10-08 00:21:11 +03:30
Reza Mobaraki ebd05c16f7
Merge branch 'develop' into stage/rezoo/e2e-test/benefactor 2024-10-02 09:50:35 +03:30
Reza Mobaraki 9458e4fa2e
test(end2end): fix
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-10-02 01:21:32 +03:30
Reza Mobaraki 00de075ad3
test(end2end): add subtests
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-10-02 01:12:58 +03:30
hossein 5f7ce41418 Merge pull request 'fix: date, date-time filter' (#187) from hotfix/Fix-refer-dates-format into develop
Reviewed-on: ebhomengo/niki#187
2024-09-25 05:31:39 +00:00
hossein c0af314119 Merge branch 'develop' into hotfix/Fix-refer-dates-format 2024-09-25 05:31:19 +00:00
hossein b25edc44eb Merge pull request 'fix(delivery): bind kindbox id path param and benefactor id' (#186) from stage/erfan/fix-get-kindbox-by-benefactor into develop
Reviewed-on: ebhomengo/niki#186
2024-09-25 05:27:39 +00:00
hossein 38875b7497 Merge branch 'develop' into stage/erfan/fix-get-kindbox-by-benefactor 2024-09-25 05:27:23 +00:00
hossein 29d25b461d Merge pull request 'fix(repository): resolve pagination 500 error on page_number field (#160)' (#185) from stage/erfan/fix-pagination into develop
Reviewed-on: ebhomengo/niki#185
2024-09-25 05:26:38 +00:00
Reza Mobaraki cc53a7ddc8
fix(BuildFilterQuery): use regex to validate date and date time
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-09-24 15:32:55 +03:30
Reza Mobaraki e006ff5898
fix: date, date-time filter
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-09-24 14:30:22 +03:30
Erfan Mohammadi 385fa2645a fix(repository): resolve pagination 500 error on page_number field (#160) 2024-09-22 23:50:02 +03:30
Erfan Mohammadi 1166c11b6f fix(delivery): bind kindbox id path param and benefactor id 2024-09-22 01:13:31 +03:30
Iman Mirazimi 4ef5c0ed66 feat(niki): sms notification for agent 2024-09-16 18:26:05 +03:30
Iman Mirazimi d26d4fc179 fix(niki): agent structure refactor 2024-09-16 14:44:45 +03:30
hossein 47b7f7f216 Merge pull request 'fix(niki): agent structure refactor' (#171) from agent-structure-refactor into develop
Reviewed-on: ebhomengo/niki#171
2024-09-16 04:52:06 +00:00
hossein 6819dde2ce Merge branch 'develop' into agent-structure-refactor 2024-09-16 04:49:41 +00:00
hossein c8c5ca808e Merge pull request 'feat(niki): implement refresh access token for admins and benefactors (#156)' (#157) from stage/ruhollahh01/implement-refresh-access-token-endpoints into develop
Reviewed-on: ebhomengo/niki#157
2024-09-16 04:49:25 +00:00
hossein 061db253fe Merge branch 'develop' into stage/ruhollahh01/implement-refresh-access-token-endpoints 2024-09-16 04:49:05 +00:00
hossein a6fd4e2357 Merge pull request 'fix(niki): fix create and update kind-box request by admin internal errors (#167 and #168)' (#172) from stage/ruhollahh01/fix-create-and-update-kindbox-req-by-admin into develop
Reviewed-on: ebhomengo/niki#172
2024-09-16 04:48:55 +00:00
Ruhollah 0703319928 fix(niki): fix create and update kind-box request by admin internal errors (#167 and #168) 2024-09-15 23:47:26 +03:30
Ruhollah e727bf5c0e feat(niki): implement refresh access token for admins and benefactors (#156) 2024-09-15 15:04:11 +03:30
Iman Mirazimi b55ec32b21 fix(niki): agent structure refactor 2024-09-15 11:06:09 +03:30
hossein 5526088b35 Merge pull request 'feat(kindbox): add edit kindbox by Admin' (#142) from stage/fatemeh/admin-edit-kindbox into develop
Reviewed-on: ebhomengo/niki#142
2024-09-11 11:01:54 +00:00
Fatemeh Javadi 8d5b12b4d5 feat(kindbox): add edit kindbox by Admin 2024-09-11 10:09:52 +03:30
hossein a3bd4247a2 Merge pull request 'refactor(param): remove embedded entities in delivery response structs' (#169) from stage/erfan/refactor-delivery-response-params into develop
Reviewed-on: ebhomengo/niki#169
2024-09-11 06:07:35 +00:00
hossein a4a6866896 Merge branch 'develop' into stage/erfan/refactor-delivery-response-params 2024-09-11 06:07:19 +00:00
hossein 243caf8f82 Merge pull request 'fix(makefile): skip formatting vendor and auto generated files' (#158) from stage/erfan/fix-makefile-format-skipping-vendor into develop
Reviewed-on: ebhomengo/niki#158
2024-09-11 05:59:03 +00:00
hossein d37253c0db Merge branch 'develop' into stage/erfan/fix-makefile-format-skipping-vendor 2024-09-11 05:58:50 +00:00
hossein 083327472c Merge pull request 'feat: add CORS middleware configuration with custom allowed origins(#154)' (#155) from stage/erfan/add-cors-configuration into develop
Reviewed-on: ebhomengo/niki#155
2024-09-11 05:58:26 +00:00
hossein c896090a7c Merge branch 'develop' into stage/erfan/add-cors-configuration 2024-09-11 05:58:16 +00:00
hossein 951f5c8114 Merge pull request 'fix(validation): Add validation for KindBox status in enumeration by admin' (#144) from stage/fatemeh/admin-kindbox-enumeration-validation into develop
Reviewed-on: ebhomengo/niki#144
2024-09-11 05:51:14 +00:00
hossein 1aab6d9d82 Merge branch 'develop' into stage/fatemeh/admin-kindbox-enumeration-validation 2024-09-11 05:50:46 +00:00
Erfan Mohammadi e5b380851c refactor(param): remove embedded entities in delivery response structs 2024-09-11 00:25:19 +03:30
Erfan Mohammadi 82e71763e2 fix(makefile): skip formatting vendor and auto generated files 2024-09-09 12:39:57 +03:30
Erfan Mohammadi 2c3124ee2c feat: add CORS middleware configuration with custom allowed origins(#154) 2024-09-08 13:34:06 +03:30
hossein 9ddcdd7a82 Merge pull request 'fix(delivery): register admin agent route to fix 404 error' (#152) from stage/ruhollahh01/fix-admin-agent-route into develop
Reviewed-on: ebhomengo/niki#152
2024-09-06 13:42:00 +00:00
Ruhollah 1e50e4c458 fix(delivery): register admin agent route to fix 404 error 2024-09-06 15:00:29 +03:30
hossein 2ebe233d8f Merge pull request 'fix(delivery): fix swagger sending request to the wrong host and port' (#151) from stage/ruhollahh01/fix-swagger-host-issue into develop
Reviewed-on: ebhomengo/niki#151
2024-09-04 15:09:08 +00:00
Ruhollah ccc56ddb03 fix(delivery): fix swagger sending request to the wrong host and port 2024-09-04 18:12:24 +03:30
hossein fab3cfa7d4 Merge pull request 'refactor(niki): stage deployment docker setup (#130)' (#148) from stage/ruhollahh01/refactor-stage-deployment-docker-setup into develop
Reviewed-on: ebhomengo/niki#148
2024-09-03 05:36:03 +00:00
hossein b2d7165ea4 Merge branch 'develop' into stage/ruhollahh01/refactor-stage-deployment-docker-setup 2024-09-03 05:28:00 +00:00
hossein 2682de1eac Merge pull request 'docs(niki): update swagger api documentation' (#147) from stage/erfan/swagger-api-docs into develop
Reviewed-on: ebhomengo/niki#147
2024-09-03 05:27:16 +00:00
hossein cad0281690 Merge branch 'develop' into stage/erfan/swagger-api-docs 2024-09-03 05:27:06 +00:00
Reza Mobaraki 92720e143f
add benefactor kind box tests
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-09-02 21:55:16 +03:30
Ruhollah 3fb173036e refactor(niki): stage deployment docker setup (#130) 2024-08-30 01:40:54 +03:30
hossein 4f4ae64100 Merge pull request 'vendorize project' (#150) from stage/hossein/vendorize into develop
Reviewed-on: ebhomengo/niki#150
2024-08-29 03:56:19 +00:00
hossein a0ac672120 vendorize project 2024-08-29 06:56:59 +03:30
Reza Mobaraki a43e973b01
fix
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-28 01:57:16 +03:30
Reza Mobaraki 73af8d30f9
add all test in one branch
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-28 01:53:01 +03:30
Reza Mobaraki 096b4dbf69
Merge branch 'stage/rezoo/e2e-test/benefator-address' into stage/rezoo/e2e-test/benefactor-kind-box-req 2024-08-28 00:28:06 +03:30
Erfan Mohammadi 97908d31b1 docs(niki): update swagger api documentation 2024-08-27 21:19:34 +03:30
Reza Mobaraki 7c1d93e1da
Chore(e2e.benefactor-address-test): all tests are applied
resolve #138

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-26 17:02:26 +03:30
Reza Mobaraki 68d6aebb3b
Fix(e2e.benefactor-address-test): fix isolation
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-26 16:58:55 +03:30
Reza Mobaraki d8bf950a89
Chore(e2e.benefactor-address-test): some changes
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-26 16:42:54 +03:30
Reza Mobaraki 17d3502854
Chore(e2e.benefactor-address-test): add tests added
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-26 16:29:53 +03:30
Reza Mobaraki c58cc2789a
Chore(e2e.benefactor-address-test): add base
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-26 00:43:45 +03:30
Fatemeh Javadi d1ebfbb525 fix(validation): Add validation for KindBox status in enumeration by admin 2024-08-24 21:51:12 +03:30
Reza Mobaraki 99f710c41d
Fix(benefactor-kindBoxReqs-test): delete test assertion
Addressed #140

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-24 14:29:46 +03:30
Reza Mobaraki 38677a0128
Refactor(benefactor-kindBoxReqs-test): use more feature of suit
Addressed #140

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-24 14:11:08 +03:30
Reza Mobaraki ceab112d0e
Refactor(benefactor-kindBoxReqs-test): use more feature of suit
Addressed #140

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-24 14:03:16 +03:30
Reza Mobaraki 79b054e09f
Refactor(benefactor-kindBoxReqs-test): move data to setupTest
Addressed #140

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-24 13:46:44 +03:30
Reza Mobaraki ae4854070c
Merge branch 'develop' into stage/rezoo/benefactor/test-e2e-kind-box-req 2024-08-24 12:21:01 +03:30
Reza Mobaraki 1c3156fe3a
Chore(benefactor-kindBoxReqs-test): add testify/suit in order to handle
Resolves #140

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-23 19:14:54 +03:30
Reza Mobaraki b132249ffc
Chore(benefactor-kindBoxReqs-test): add testify/suit in order to handle
- test Update benefactorKindBoxReqs

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-23 19:05:30 +03:30
Reza Mobaraki 15f37001db
Chore(benefactor-kindBoxReqs-test): make it cleaner
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-23 17:58:44 +03:30
Reza Mobaraki 6c78c8098a
Chore(benefactor-kindBoxReqs-test): add tests
- Get_Success
- GetAll_Success
- Create_Success

Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-23 15:54:27 +03:30
Reza Mobaraki 16f37c0f64
Chore(MakeFile): add .PHONY
Signed-off-by: Reza Mobaraki <rezam578@gmail.com>
2024-08-22 18:32:36 +03:30
2414 changed files with 686524 additions and 5958 deletions

4
.gitignore vendored
View File

@ -18,9 +18,9 @@ activate.mise.toml
*.out
# Dependency directories (remove the comment below to include it)
vendor/
.idea
bin
tmp
#.env
*.env
@ -28,3 +28,5 @@ bin
# Logs
logs/
mise.log
curl

View File

@ -1,37 +1,29 @@
# Build Stage
# First pull Golang image
FROM golang:1.21.3-alpine as builder
FROM golang:1.23.0-alpine AS builder
# Set environment variable
ENV APP_NAME niki
ENV CMD_PATH main.go
# Add a work directory
WORKDIR /$APP_NAME
## Cache and install dependencies
#COPY go.mod go.sum ./
#RUN go mod download
# Copy app files
COPY . .
# Budild application
RUN CGO_ENABLED=0 go build -mod=mod -v -o $APP_NAME .
RUN CGO_ENABLED=0 go build -mod=vendor -v -o $APP_NAME .
# Run Stage
FROM alpine:3.20 AS runtime
FROM alpine:3.18 as development
# Copy the binary from the builder stage
COPY --from=builder /niki/niki .
# Copy migration files
COPY --from=builder /niki/repository/mysql/migration ./repository/mysql/migration
# Set environment variable
ENV APP_NAME niki
# Copy only required data into this image
COPY --from=builder /$APP_NAME .
# Expose application port
EXPOSE 1313
# Start app
CMD ./$APP_NAME
EXPOSE 8313
# Start the application
CMD ["./niki", "--migrate"]

View File

@ -1,7 +1,9 @@
// TODO: add commands for build and run in dev/produciton mode
# TODO: add commands for build and run in dev/produciton mode
ROOT=$(realpath $(dir $(lastword $(MAKEFILE_LIST))))
.PHONY: help confirm lint test format build run docker swagger watch migrate/status migrate/new migrate/up migrate/down
confirm:
@echo -n 'Are you sure? [y/N] ' && read ans && [ $${ans:-N} = y ]
@ -16,12 +18,12 @@ format:
@which gofumpt || (go install mvdan.cc/gofumpt@latest)
@gofumpt -l -w $(ROOT)
@which gci || (go install github.com/daixiang0/gci@latest)
@gci write $(ROOT)
@gci write $(ROOT) --skip-generated --skip-vendor
@which golangci-lint || (go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.0)
@golangci-lint run --fix
build:
go build main.go --migrate
go build -o niki main.go
run:
go run main.go --migrate

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# Niki
---
## Prerequisites
- **Go 1.25.4** (Ensure your Go version matches this requirement)
- **Docker 20.10+** (or higher)
- **Git**
---
## Installation
### 1. Configure Go Module Mirror
To accelerate dependency downloads, set the Go module mirror to **Megan** (Iranian Go mirror):
```url
https://megan.ir/hub/go
```
### 2. Install Dependencies
```bash
go mod tidy
go mod vendor
```
### 3. Configure Environment
Copy the example environment file and customize it:
```bash
cp .env.example .env
```
---
## Running the Application
### 1. Start Services
Launch the database and Redis services using Docker Compose:
```bash
docker compose up -d
```
> 🌐 *Docker images are sourced from [Arvan Cloud's Docker repositories](https://www.arvancloud.ir/fa/dev/docker). Ensure
your environment has access to these repositories.*
### 2. Apply Database Migrations
Initialize the database schema:
```bash
go run main.go --migrate
```
### 3. Start the Application
Run the application in development mode:
```bash
go run main.go
```
> ✨ **Alternative**: Use the provided `Makefile` for streamlined execution:
> [Makefile](Makefile)

8
benefactorapp/app.go Normal file
View File

@ -0,0 +1,8 @@
package benefactorapp
import "net/http"
type Application struct {
Config Config
HTTPServer *http.Server
}

11
benefactorapp/config.go Normal file
View File

@ -0,0 +1,11 @@
package benefactorapp
type Config struct {
// HTTP server config
// Database config
// Logger config
// Service config
}

View File

@ -0,0 +1,17 @@
package http
import (
"net/http"
"github.com/labstack/echo/v4"
)
type Handler struct{}
func NewHandler() *Handler {
return &Handler{}
}
func (h Handler) HealthCheck(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]string{"status": "ok"})
}

View File

@ -0,0 +1 @@
package http

View File

@ -0,0 +1,23 @@
package http
import httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
type Server struct {
HTTPServer *httpserver.Server
Handler *Handler
}
func NewServer(httpserver *httpserver.Server) *Server {
return &Server{
HTTPServer: httpserver,
Handler: NewHandler(),
}
}
func (s *Server) Serve() {
}
func (s *Server) Stop() {}
func (s *Server) RegisterRoutes() {}

View File

@ -0,0 +1,13 @@
package database
import "git.gocasts.ir/ebhomengo/niki/repository/mysql"
type DB struct {
conn *mysql.DB
}
func New(conn *mysql.DB) *DB {
return &DB{
conn: conn,
}
}

View File

@ -0,0 +1 @@
package service

View File

@ -0,0 +1 @@
package service

View File

@ -0,0 +1 @@
package service

View File

@ -0,0 +1 @@
package service

View File

@ -20,10 +20,6 @@ redis:
password: ""
db: 0
sms_provider:
host: localhost
port: 443
benefactor_service:
length_of_otp_code: 5
@ -33,6 +29,7 @@ kavenegar_sms_provider:
admin_auth:
sign_key: admin-jwt_secret_test_nik
token: "e18Ef8EAf2116e09A737c0b23B2Bd08D"

View File

@ -10,7 +10,12 @@ import (
)
type HTTPServer struct {
Port int `koanf:"port"`
Port int `koanf:"port"`
Cors Cors `koanf:"cors"`
}
type Cors struct {
AllowOrigins []string `koanf:"allow_origins"`
}
type Config struct {

View File

@ -0,0 +1,13 @@
package adminaddresshandler
import (
param "git.gocasts.ir/ebhomengo/niki/param/admin/address"
admincityparam "git.gocasts.ir/ebhomengo/niki/param/admin/city"
adminprovinceparam "git.gocasts.ir/ebhomengo/niki/param/admin/province"
)
type Address struct {
Address param.Data `json:"address"`
Province adminprovinceparam.Data `json:"province"`
City admincityparam.Data `json:"city"`
}

View File

@ -10,7 +10,7 @@ import (
// LoginByPhoneNumber godoc
// @Summary Admin login by PhoneNumber
// @Tags Admin
// @Tags Admins
// @Accept json
// @Produce json
// @Param Request body adminserviceparam.LoginWithPhoneNumberRequest true "Admin login request body"

View File

@ -0,0 +1,47 @@
package adminhandler
import (
"net/http"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Profile godoc
// @Summary Admin profile
// @Tags Admins
// @Accept json
// @Produce json
// @Success 200 {object} adminserviceparam.ProfileResponse
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/profile [get].
func (h Handler) Profile(c echo.Context) error {
var req adminserviceparam.ProfileRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.AdminID = claim.GetClaimsFromEchoContext(c).UserID
resp, sErr := h.adminSvc.AdminGetProfile(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -0,0 +1,37 @@
package adminhandler
import (
"net/http"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// RefreshAccess godoc
// @Summary Get a new access token by providing a refresh token
// @Tags Admins
// @Accept json
// @Produce json
// @Param Request body adminserviceparam.RefreshAccessRequest true "Refresh access request body"
// @Success 200 {object} adminserviceparam.RefreshAccessResponse
// @Failure 400 {string} "Bad Request"
// @Failure 422 {string} "invalid or expired jwt"
// @Failure 500 {string} "something went wrong"
// @Router /admins/refresh-access [post].
func (h Handler) RefreshAccess(c echo.Context) error {
var req adminserviceparam.RefreshAccessRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, err := h.adminSvc.RefreshAccess(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -10,7 +10,7 @@ import (
// Register godoc
// @Summary Register an admin by super-admin
// @Tags Admin
// @Tags Admins
// @Accept json
// @Produce json
// @Param Request body adminserviceparam.RegisterRequest true "Admin Register Request Body"

View File

@ -13,6 +13,8 @@ func (h Handler) SetRoutes(e *echo.Echo) {
//r.POST("/", h.Add).Name = "admin-addkindboxreq"
r.POST("/register", h.Register, middleware.Auth(h.authSvc), middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminAdminRegisterPermission))
r.POST("/login-by-phone", h.LoginByPhoneNumber)
r.POST("/refresh-access", h.RefreshAccess)
r.GET("/profile", h.Profile, middleware.Auth(h.authSvc))
//nolint:gocritic
//r.PATCH("/:id", h.Update).Name = "admin-updatekindboxreq"
}

View File

@ -10,7 +10,7 @@ import (
// GetAllAgent godoc
// @Summary Get all agents by admin
// @Tags Admin
// @Tags Admins
// @Accept json
// @Produce json
// @Success 200 {object} adminagentparam.GetAllAgentResponse

View File

@ -0,0 +1,25 @@
package adminbenefactorhandler
import (
"time"
"git.gocasts.ir/ebhomengo/niki/entity"
adminaddressparam "git.gocasts.ir/ebhomengo/niki/param/admin/address"
adminkindboxparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
adminkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
)
type BenefactorAggregatedResponse struct {
ID uint `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
PhoneNumber string `json:"phone_number"`
Description string `json:"description"`
Email string `json:"email"`
Gender entity.Gender `json:"gender"`
BirthDate *time.Time `json:"birth_date"`
Status entity.BenefactorStatus `json:"status"`
Addresses []adminaddressparam.Data `json:"addresses"`
KindBoxes []adminkindboxparam.Data `json:"kind_boxes"`
KindBoxReqs []adminkindboxreqparam.Data `json:"kind_box_reqs"`
}

View File

@ -0,0 +1,106 @@
package adminbenefactorhandler
import (
"net/http"
params "git.gocasts.ir/ebhomengo/niki/param"
adminaddressparam "git.gocasts.ir/ebhomengo/niki/param/admin/address"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
adminkindboxparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
adminkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// GetBenefactor godoc
// @Summary Get benefactor details by id
// @Description This endpoint retrieves details for a specific benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Success 200 {object} BenefactorAggregatedResponse
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id} [get].
func (h Handler) GetBenefactor(c echo.Context) error {
var req param.GetBenefactorByIDRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
bnf, err := h.benefactorSvc.GetByID(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
addresses, err := h.addressSvc.GetAll(c.Request().Context(), adminaddressparam.GetAllAddressesRequest{
BenefactorID: bnf.Data.ID,
})
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
kindBoxes, err := h.kindBoxSvc.GetAll(c.Request().Context(), adminkindboxparam.KindBoxGetAllRequest{
Pagination: params.PaginationRequest{
PageSize: 50,
PageNumber: 1,
},
Sort: params.SortRequest{
Field: "created_at",
Direction: params.DescSortDirection,
},
Filter: map[string]any{
"benefactor_id": bnf.Data.ID,
},
})
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
kindBoxReqs, err := h.kindBoxReqSvc.GetAll(c.Request().Context(), adminkindboxreqparam.KindBoxReqGetAllRequest{
Pagination: params.PaginationRequest{
PageSize: 50,
PageNumber: 1,
},
Sort: params.SortRequest{
Field: "created_at",
Direction: params.DescSortDirection,
},
Filter: map[string]any{
"benefactor_id": bnf.Data.ID,
},
})
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
resp := BenefactorAggregatedResponse{
ID: bnf.Data.ID,
FirstName: bnf.Data.FirstName,
LastName: bnf.Data.LastName,
PhoneNumber: bnf.Data.PhoneNumber,
Description: bnf.Data.Description,
Email: bnf.Data.Email,
Gender: bnf.Data.Gender,
BirthDate: bnf.Data.BirthDate,
Status: bnf.Data.Status,
Addresses: addresses.Data,
KindBoxes: kindBoxes.Data,
KindBoxReqs: kindBoxReqs.Data,
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -0,0 +1,59 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"
)
// GetAllBenefactor godoc
// @Summary Get all benefactors by admin
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param search query string false "Search by id, phone_number, concat(first_name, last_name) benefactor"
// @Param filter_id query int false "Filter by ID"
// @Param filter_first_name query string false "Filter by first_name"
// @Param filter_last_name query string false "Filter by last_name"
// @Param filter_phone_number query string false "Filter by phone_number"
// @Param filter_email query string false "Filter by email"
// @Param filter_status query string false "Filter by status" Enums(active,inactive)
// @Param page_number query int false "Page number"
// @Param page_size query int false "Page size"
// @Param sort_field query string false "Sort by field" Enums(id,first_name,last_name,phone_number,email,status,created_at)
// @Param sort_direction query string false "Sort order" Enums(asc,desc)
// @Success 200 {object} param.BenefactorGetAllResponse
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors [get].
func (h Handler) GetAllBenefactor(c echo.Context) error {
var req param.BenefactorGetAllRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.Filter = queryparam.GetFilterParams(c)
resp, sErr := h.benefactorSvc.GetAllBenefactor(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -0,0 +1,36 @@
package adminbenefactorhandler
import (
adminaddressservice "git.gocasts.ir/ebhomengo/niki/service/admin/address"
authorizeservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
benefactorservice "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor"
adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
)
type Handler struct {
authSvc authservice.Service
authorizeSvc authorizeservice.Service
benefactorSvc benefactorservice.Service
addressSvc adminaddressservice.Service
kindBoxSvc adminkindboxservice.Service
kindBoxReqSvc adminkindboxreqservice.Service
}
func New(authSvc authservice.Service,
authorizeSvc authorizeservice.Service,
benefactorSvc benefactorservice.Service,
addressSvc adminaddressservice.Service,
kindBoxSvc adminkindboxservice.Service,
kindBoxReqSvc adminkindboxreqservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
authorizeSvc: authorizeSvc,
benefactorSvc: benefactorSvc,
addressSvc: addressSvc,
kindBoxSvc: kindBoxSvc,
kindBoxReqSvc: kindBoxReqSvc,
}
}

View File

@ -0,0 +1,18 @@
package adminbenefactorhandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
"github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admins/benefactors")
r.Use(middleware.Auth(h.authSvc))
r.GET("", h.GetAllBenefactor, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorGetAllPermission))
r.GET("/:id", h.GetBenefactor, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorGetPermission))
r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorUpdatePermission))
r.PUT("/:id/status", h.UpdateStatus, middleware.AdminAuthorization(h.authorizeSvc, entity.AdminBenefactorUpdateStatusPermission))
}

View File

@ -0,0 +1,47 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Update godoc
// @Summary Update benefactor details by admin
// @Description This endpoint update specific benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Param Request body param.BenefactorUpdateRequest true "Update Benefactor Body"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.BenefactorUpdateRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, sErr := h.benefactorSvc.Update(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -0,0 +1,46 @@
package adminbenefactorhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// UpdateStatus godoc
// @Summary Update benefactor status by admin
// @Description This endpoint update status (active/inactive) benefactor.
// @Tags Admins Benefactors
// @Accept json
// @Produce json
// @Param id path int true "Benefactor ID"
// @Param Request body param.BenefactorUpdateStatusRequest true "Update Benefactor Status"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/benefactors/{id}/status [put].
func (h Handler) UpdateStatus(c echo.Context) error {
var req param.BenefactorUpdateStatusRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, sErr := h.benefactorSvc.UpdateStatus(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -11,7 +11,7 @@ import (
// AssignReceiverAgent godoc
// @Summary Admin assign receiver agent to kindbox
// @Tags KindBox
// @Tags Admins KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -19,7 +19,7 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxes/assign-receiver-agent/{id} [patch].
// @Router /admins/kindboxes/{id}/assign-receiver-agent [patch].
func (h Handler) AssignReceiverAgent(c echo.Context) error {
var req param.AssignReceiverRequest

View File

@ -0,0 +1,65 @@
package adminkindboxhandler
import (
"time"
adminaddresshandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/address"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/param"
adminbenefactorparam "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
adminrefertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
)
type KindBoxAggregatedResponse struct {
ID uint `json:"id"`
KindBoxReqID uint `json:"kind_box_req_id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
Amount uint `json:"amount"`
SerialNumber string `json:"serial_number"`
Status entity.KindBoxStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt time.Time `json:"delivered_at"`
ReturnReferTimeID uint `json:"return_refer_time_id"`
ReturnReferDate *time.Time `json:"return_refer_date"`
ReturnAddressID uint `json:"return_address_id"`
ReceiverAgentID uint `json:"receiver_agent_id"`
ReturnedAt *time.Time `json:"returned_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
DeliverAddress adminaddresshandler.Address `json:"deliver_address"`
DeliverReferTime adminrefertimeparam.Data `json:"deliver_refer_time"`
ReturnAddress adminaddresshandler.Address `json:"return_address"`
ReturnReferTime adminrefertimeparam.Data `json:"return_refer_time"`
}
type KindBoxAggregatedListResponse struct {
ID uint `json:"id"`
KindBoxReqID uint `json:"kind_box_req_id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
Amount uint `json:"amount"`
SerialNumber string `json:"serial_number"`
Status entity.KindBoxStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt time.Time `json:"delivered_at"`
ReturnReferTimeID uint `json:"return_refer_time_id"`
ReturnReferDate *time.Time `json:"return_refer_date"`
ReturnAddressID uint `json:"return_address_id"`
ReceiverAgentID uint `json:"receiver_agent_id"`
ReturnedAt *time.Time `json:"returned_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
DeliverReferTime adminrefertimeparam.Data `json:"deliver_refer_time"`
ReturnReferTime adminrefertimeparam.Data `json:"return_refer_time"`
}
type KindBoxesAggregatedResponse struct {
Data []KindBoxAggregatedListResponse `json:"data"`
Pagination param.PaginationResponse `json:"pagination"`
FieldErrors map[string]string `json:"field_errors,omitempty"`
}

View File

@ -11,7 +11,7 @@ import (
// Enumerate godoc
// @Summary Admin enumerate kindbox
// @Tags KindBox
// @Tags Admins KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -23,7 +23,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admin/kindboxes/{id}/enumerate [patch].
// @Router /admins/kindboxes/{id}/enumerate [patch].
func (h Handler) Enumerate(c echo.Context) error {
var req param.EnumerateKindBoxRequest

View File

@ -11,32 +11,95 @@ import (
// Get godoc
// @Summary Get a specific kind box by admin
// @Description This endpoint retrieves a specific kind box by admin
// @Tags KindBox
// @Tags Admins KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "Kind box ID"
// @Success 200 {object} param.KindBoxGetResponse
// @Success 200 {object} KindBoxAggregatedResponse
// @Failure 400 {string} "Bad request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 404 {string} "record not found"
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admin/kindboxes/{id} [get].
// @Router /admins/kindboxes/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.KindBoxGetRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, sErr := h.adminKindBoxSvc.Get(c.Request().Context(), req)
kindBox, sErr := h.adminKindBoxSvc.Get(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
if kindBox.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
"errors": kindBox.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactor, bErr := h.adminBenefactorAggSvc.GetByID(c.Request().Context(), kindBox.Data.BenefactorID)
if bErr != nil {
msg, code := httpmsg.Error(bErr)
return echo.NewHTTPError(code, msg)
}
deliverAddress, dAErr := h.addressAggSvc.GetAggregatedByID(c.Request().Context(), kindBox.Data.DeliverAddressID)
if dAErr != nil {
msg, code := httpmsg.Error(dAErr)
return echo.NewHTTPError(code, msg)
}
returnAddress, rAErr := h.addressAggSvc.GetAggregatedByID(c.Request().Context(), kindBox.Data.ReturnAddressID)
if rAErr != nil {
msg, code := httpmsg.Error(rAErr)
return echo.NewHTTPError(code, msg)
}
deliverReferTime, dRErr := h.referTimeAggSvc.GetReferTimeByID(c.Request().Context(), kindBox.Data.DeliverReferTimeID)
if dRErr != nil {
msg, code := httpmsg.Error(dRErr)
return echo.NewHTTPError(code, msg)
}
returnReferTime, rRErr := h.referTimeAggSvc.GetReferTimeByID(c.Request().Context(), kindBox.Data.ReturnReferTimeID)
if rRErr != nil {
msg, code := httpmsg.Error(rRErr)
return echo.NewHTTPError(code, msg)
}
resp := KindBoxAggregatedResponse{
ID: kindBox.Data.ID,
KindBoxReqID: kindBox.Data.KindBoxReqID,
BenefactorID: kindBox.Data.BenefactorID,
KindBoxType: kindBox.Data.KindBoxType,
Amount: kindBox.Data.Amount,
SerialNumber: kindBox.Data.SerialNumber,
Status: kindBox.Data.Status,
DeliverReferTimeID: kindBox.Data.DeliverReferTimeID,
DeliverReferDate: kindBox.Data.DeliverReferDate,
DeliverAddressID: kindBox.Data.DeliverAddressID,
SenderAgentID: kindBox.Data.SenderAgentID,
DeliveredAt: kindBox.Data.DeliveredAt,
ReturnReferTimeID: kindBox.Data.ReturnReferTimeID,
ReturnReferDate: kindBox.Data.ReturnReferDate,
ReturnAddressID: kindBox.Data.ReturnAddressID,
ReceiverAgentID: kindBox.Data.ReceiverAgentID,
ReturnedAt: kindBox.Data.ReturnedAt,
Benefactor: benefactor,
DeliverAddress: deliverAddress,
ReturnAddress: returnAddress,
DeliverReferTime: deliverReferTime,
ReturnReferTime: returnReferTime,
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -4,6 +4,7 @@ import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
arrayfunc "git.gocasts.ir/ebhomengo/niki/pkg/array_func"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
"github.com/labstack/echo/v4"
@ -12,13 +13,14 @@ import (
// GetAll godoc
// @Summary Get all KindBoxes by admin
// @Description Retrieves a list of all KindBoxes with filtering, sorting, and pagination options
// @Tags KindBox
// @Tags Admins KindBoxes
// @Accept json
// @Produce json
// @Param search query string false "Search by id, phone_number, concat(first_name, last_name) benefactor"
// @Param filter_id query int false "Filter by ID"
// @Param filter_kind_box_req_id query int false "Filter by KindBox request ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_kind_box_type query string false "Filter by KindBox type" Enums(on-table,cylindrical,stand-up)
// @Param filter_type query string false "Filter by KindBox type" Enums(on-table,cylindrical,stand-up)
// @Param filter_amount query int false "Filter by amount"
// @Param filter_serial_number query string false "Filter by serial number"
// @Param filter_status query string false "Filter by status" Enums(delivered,ready-to-return,assigned-receiver-agent,returned,enumerated)
@ -36,10 +38,10 @@ import (
// @Param page_size query int false "Page size"
// @Param sort_field query string false "Sort by field" Enums(id,kind_box_req_id,benefactor_id,kind_box_type,amount,serial_number,status,delivered_at,return_refer_time_id,return_refer_date,return_address_id,receiver_agent_id,returned_at,sender_agent_id,deliver_refer_date,deliver_address_id,deliver_refer_time_id)
// @Param sort_direction query string false "Sort order" Enums(asc,desc)
// @Success 200 {object} param.KindBoxGetAllResponse
// @Success 200 {array} KindBoxesAggregatedResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxes [get].
// @Router /admins/kindboxes [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.KindBoxGetAllRequest
@ -49,18 +51,94 @@ func (h Handler) GetAll(c echo.Context) error {
req.Filter = queryparam.GetFilterParams(c)
resp, sErr := h.adminKindBoxSvc.GetAll(c.Request().Context(), req)
kindBoxes, sErr := h.adminKindBoxSvc.GetAll(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
if kindBoxes.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
"errors": kindBoxes.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactors, bErr := h.adminBenefactorAggSvc.GetByIDs(c.Request().Context(), getBenefactorIDs(kindBoxes.Data))
if bErr != nil {
msg, code := httpmsg.Error(sErr)
return echo.NewHTTPError(code, msg)
}
deliverReferTime, dRErr := h.referTimeAggSvc.GetReferTimeByIDs(c.Request().Context(), getDeliverReferTimeIDs(kindBoxes.Data))
if dRErr != nil {
msg, code := httpmsg.Error(dRErr)
return echo.NewHTTPError(code, msg)
}
returnReferTime, rRErr := h.referTimeAggSvc.GetReferTimeByIDs(c.Request().Context(), getReturnReferTimeIDs(kindBoxes.Data))
if rRErr != nil {
msg, code := httpmsg.Error(rRErr)
return echo.NewHTTPError(code, msg)
}
var data []KindBoxAggregatedListResponse
for _, kindBox := range kindBoxes.Data {
data = append(data, KindBoxAggregatedListResponse{
ID: kindBox.ID,
KindBoxReqID: kindBox.KindBoxReqID,
BenefactorID: kindBox.BenefactorID,
KindBoxType: kindBox.KindBoxType,
Amount: kindBox.Amount,
SerialNumber: kindBox.SerialNumber,
Status: kindBox.Status,
DeliverReferTimeID: kindBox.DeliverReferTimeID,
DeliverReferDate: kindBox.DeliverReferDate,
DeliverAddressID: kindBox.DeliverAddressID,
SenderAgentID: kindBox.SenderAgentID,
DeliveredAt: kindBox.DeliveredAt,
ReturnReferTimeID: kindBox.ReturnReferTimeID,
ReturnReferDate: kindBox.ReturnReferDate,
ReturnAddressID: kindBox.ReturnAddressID,
ReceiverAgentID: kindBox.ReceiverAgentID,
ReturnedAt: kindBox.ReturnedAt,
Benefactor: benefactors[kindBox.BenefactorID],
DeliverReferTime: deliverReferTime[kindBox.DeliverReferTimeID],
ReturnReferTime: returnReferTime[kindBox.ReturnReferTimeID],
})
}
resp := KindBoxesAggregatedResponse{
Data: data,
Pagination: kindBoxes.Pagination,
}
return c.JSON(http.StatusOK, resp)
}
func getBenefactorIDs(kindBoxes []param.Data) []any {
benefactorsMap := make(map[uint]bool)
for _, kindBox := range kindBoxes {
benefactorsMap[kindBox.BenefactorID] = true
}
return arrayfunc.MapToSlice(benefactorsMap)
}
func getDeliverReferTimeIDs(kindBoxes []param.Data) []any {
deliverReferTimesMap := make(map[uint]bool)
for _, kindBox := range kindBoxes {
deliverReferTimesMap[kindBox.DeliverReferTimeID] = true
}
return arrayfunc.MapToSlice(deliverReferTimesMap)
}
func getReturnReferTimeIDs(kindBoxes []param.Data) []any {
returnReferTimesMap := make(map[uint]bool)
for _, kindBox := range kindBoxes {
returnReferTimesMap[kindBox.ReturnReferTimeID] = true
}
return arrayfunc.MapToSlice(returnReferTimesMap)
}

View File

@ -1,28 +1,40 @@
package adminkindboxhandler
import (
adminaddressaggservice "git.gocasts.ir/ebhomengo/niki/service/admin/address_aggregator"
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
adminbenefactoraggsvc "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor_aggregator"
adminkindboxservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box"
adminrefertimeaggregatorservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time_aggregator"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
adminKindBoxSvc adminkindboxservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
authSvc authservice.Service
adminKindBoxSvc adminkindboxservice.Service
adminBenefactorAggSvc adminbenefactoraggsvc.Service
addressAggSvc adminaddressaggservice.Service
referTimeAggSvc adminrefertimeaggregatorservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
adminKindBoxSvc adminkindboxservice.Service,
adminBenefactorAggSvc adminbenefactoraggsvc.Service,
addressAggSvc adminaddressaggservice.Service,
referTimeAggSvc adminrefertimeaggregatorservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminKindBoxSvc: adminKindBoxSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
authSvc: authSvc,
adminKindBoxSvc: adminKindBoxSvc,
adminBenefactorAggSvc: adminBenefactorAggSvc,
addressAggSvc: addressAggSvc,
referTimeAggSvc: referTimeAggSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -7,12 +7,13 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admin/kindboxes")
r := e.Group("/admins/kindboxes")
r.Use(middleware.Auth(h.authSvc))
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetPermission))
r.PATCH("/assign-receiver-agent/:id", h.AssignReceiverAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxAssignReceiverAgentPermission))
r.PATCH("/:id/assign-receiver-agent", h.AssignReceiverAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxAssignReceiverAgentPermission))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetAllPermission))
r.PATCH("/:id/enumerate", h.Enumerate, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxEnumeratePermission))
r.PUT("/update/:id", h.Update, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxUpdatePermission))
}

View File

@ -0,0 +1,49 @@
package adminkindboxhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// Update godoc
// @Summary Update kind Box by admin
// @Tags Admins KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "Kind Box ID"
// @Param Request body param.KindBoxUpdateRequest true "Update KindBox Request Body"
// @Success 204
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /admins/kindboxes/update/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.KindBoxUpdateRequest
if bErr := c.Bind(&req); bErr != nil {
return c.JSON(http.StatusBadRequest, httpmsg.ErrorResponse{
Message: "Invalid request body",
})
}
resp, sErr := h.adminKindBoxSvc.Update(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, nil)
}

View File

@ -13,7 +13,7 @@ import (
// Accept godoc
// @Summary Accept kind box request by admin
// @Tags KindBoxReq
// @Tags Admins KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -21,7 +21,7 @@ import (
// @Success 200 {object} param.KindBoxReqAcceptResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/accept-kind-box-req/{id} [patch].
// @Router /admins/kindboxreqs/{id}/accept-kind-box-req [patch].
func (h Handler) Accept(c echo.Context) error {
var req param.KindBoxReqAcceptRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -11,14 +11,14 @@ import (
// AddKindBoxReq godoc
// @Summary Add a new kind box request for a benefactor by admin
// @Tags KindBoxReq
// @Tags Admins KindBoxReqs
// @Accept json
// @Produce json
// @Param Request body param.KindBoxReqAddRequest true "New kind box request details"
// @Success 200 {object} param.KindBoxReqAddResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs [post].
// @Router /admins/kindboxreqs [post].
func (h Handler) AddKindBoxReq(c echo.Context) error {
req := param.KindBoxReqAddRequest{}
if err := c.Bind(&req); err != nil {

View File

@ -13,7 +13,7 @@ import (
// AssignSenderAgent godoc
// @Summary Admin Assign Sender Agent to kindboxreq
// @Tags KindBoxReq
// @Tags Admins KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -21,7 +21,7 @@ import (
// @Success 200 {object} param.AssignSenderResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/assign-sender-agent/{id} [patch].
// @Router /admins/kindboxreqs/{id}/assign-sender-agent [patch].
func (h Handler) AssignSenderAgent(c echo.Context) error {
var req param.AssignSenderRequest

View File

@ -0,0 +1,51 @@
package adminkindboxreqhandler
import (
"time"
adminaddresshandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/address"
"git.gocasts.ir/ebhomengo/niki/entity"
"git.gocasts.ir/ebhomengo/niki/param"
adminbenefactorparam "git.gocasts.ir/ebhomengo/niki/param/admin/benefactor"
adminrefertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
)
type KindBoxReqAggregatedResponse struct {
ID uint `json:"id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
CountRequested uint `json:"count_requested"`
CountAccepted uint `json:"count_accepted"`
Description string `json:"description"`
Status entity.KindBoxReqStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt *time.Time `json:"delivered_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
DeliverAddress adminaddresshandler.Address `json:"deliver_address"`
DeliverReferTime adminrefertimeparam.Data `json:"deliver_refer_time"`
}
type KindBoxReqAggregatedListResponse struct {
ID uint `json:"id"`
BenefactorID uint `json:"benefactor_id"`
KindBoxType entity.KindBoxType `json:"kind_box_type"`
CountRequested uint `json:"count_requested"`
CountAccepted uint `json:"count_accepted"`
Description string `json:"description"`
Status entity.KindBoxReqStatus `json:"status"`
DeliverReferTimeID uint `json:"deliver_refer_time_id"`
DeliverReferDate time.Time `json:"deliver_refer_date"`
DeliverAddressID uint `json:"deliver_address_id"`
SenderAgentID uint `json:"sender_agent_id"`
DeliveredAt *time.Time `json:"delivered_at"`
Benefactor adminbenefactorparam.Data `json:"benefactor"`
}
type KindBoxReqsAggregatedResponse struct {
Data []KindBoxReqAggregatedListResponse `json:"data"`
Pagination param.PaginationResponse `json:"pagination"`
FieldErrors map[string]string `json:"field_errors,omitempty"`
}

View File

@ -10,11 +10,11 @@ import (
// Get godoc
// @Summary Get a specific kind box req by ID
// @Tags KindBoxReq
// @Tags Admins KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
// @Success 200 {object} param.GetKindBoxReqResponse
// @Success 200 {object} KindBoxReqAggregatedResponse
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
@ -28,18 +28,56 @@ func (h Handler) Get(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, err := h.adminKindBoxReqSvc.Get(c.Request().Context(), req)
kindBoxReq, err := h.adminKindBoxReqSvc.Get(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
if resp.FieldErrors != nil {
if kindBoxReq.FieldErrors != nil {
return c.JSON(code, echo.Map{
"message": msg,
"errors": resp.FieldErrors,
"errors": kindBoxReq.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactor, bErr := h.adminBenefactorAggSvc.GetByID(c.Request().Context(), kindBoxReq.Data.BenefactorID)
if bErr != nil {
msg, code := httpmsg.Error(bErr)
return echo.NewHTTPError(code, msg)
}
deliverAddress, dAErr := h.addressAggSvc.GetAggregatedByID(c.Request().Context(), kindBoxReq.Data.DeliverAddressID)
if dAErr != nil {
msg, code := httpmsg.Error(dAErr)
return echo.NewHTTPError(code, msg)
}
deliverReferTime, dRErr := h.referTimeAggSvc.GetReferTimeByID(c.Request().Context(), kindBoxReq.Data.DeliverReferTimeID)
if dRErr != nil {
msg, code := httpmsg.Error(dRErr)
return echo.NewHTTPError(code, msg)
}
resp := KindBoxReqAggregatedResponse{
ID: kindBoxReq.Data.ID,
BenefactorID: kindBoxReq.Data.BenefactorID,
KindBoxType: kindBoxReq.Data.KindBoxType,
CountRequested: kindBoxReq.Data.CountRequested,
CountAccepted: kindBoxReq.Data.CountAccepted,
Description: kindBoxReq.Data.Description,
Status: kindBoxReq.Data.Status,
DeliverReferTimeID: kindBoxReq.Data.DeliverReferTimeID,
DeliverReferDate: kindBoxReq.Data.DeliverReferDate,
DeliverAddressID: kindBoxReq.Data.DeliverAddressID,
SenderAgentID: kindBoxReq.Data.SenderAgentID,
DeliveredAt: kindBoxReq.Data.DeliveredAt,
Benefactor: benefactor,
DeliverAddress: deliverAddress,
DeliverReferTime: deliverReferTime,
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -4,6 +4,7 @@ import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
arrayfunc "git.gocasts.ir/ebhomengo/niki/pkg/array_func"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
echo "github.com/labstack/echo/v4"
@ -12,9 +13,10 @@ import (
// GetAll godoc
// @Summary Admin get all kindboxreq
// @Description Retrieves a list of all KindBox requests with filtering, sorting, and pagination options
// @Tags KindBoxReq
// @Tags Admins KindBoxReqs
// @Accept json
// @Produce json
// @Param search query string false "Search by id, phone_number, concat(first_name, last_name) benefactor"
// @Param filter_id query int false "Filter by ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_sender_agent_id query int false "Filter by sender agent ID"
@ -30,7 +32,7 @@ import (
// @Param page_size query int false "Page size"
// @Param sort_field query string false "Sort by field" Enums(id,benefactor_id,sender_agent_id,kind_box_type,status,count_requested,count_accepted,deliver_refer_time_id,deliver_refer_date,deliver_address_id,delivered_at)
// @Param sort_direction query string false "Sort order" Enums(asc,desc)
// @Success 200 {object} param.KindBoxReqGetAllResponse
// @Success 200 {array} KindBoxReqsAggregatedResponse
// @Failure 400 {string} "Bad Request"
// @Failure 401 {string} "invalid or expired jwt"
// @Failure 403 {string} "user not allowed"
@ -47,18 +49,55 @@ func (h Handler) GetAll(c echo.Context) error {
req.Filter = queryparam.GetFilterParams(c)
resp, err := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req)
kindBoxReqs, err := h.adminKindBoxReqSvc.GetAll(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
if resp.FieldErrors != nil {
if kindBoxReqs.FieldErrors != nil {
return c.JSON(code, httpmsg.ErrorResponse{
Message: msg,
Errors: resp.FieldErrors,
Errors: kindBoxReqs.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
benefactors, bErr := h.adminBenefactorAggSvc.GetByIDs(c.Request().Context(), getBenefactorIDs(kindBoxReqs.Data))
if bErr != nil {
msg, code := httpmsg.Error(bErr)
return echo.NewHTTPError(code, msg)
}
var data []KindBoxReqAggregatedListResponse
for _, kindBoxReq := range kindBoxReqs.Data {
data = append(data, KindBoxReqAggregatedListResponse{
ID: kindBoxReq.ID,
BenefactorID: kindBoxReq.BenefactorID,
KindBoxType: kindBoxReq.KindBoxType,
CountRequested: kindBoxReq.CountRequested,
CountAccepted: kindBoxReq.CountAccepted,
Description: kindBoxReq.Description,
Status: kindBoxReq.Status,
DeliverReferTimeID: kindBoxReq.DeliverReferTimeID,
DeliverReferDate: kindBoxReq.DeliverReferDate,
DeliverAddressID: kindBoxReq.DeliverAddressID,
SenderAgentID: kindBoxReq.SenderAgentID,
DeliveredAt: kindBoxReq.DeliveredAt,
Benefactor: benefactors[kindBoxReq.BenefactorID],
})
}
resp := KindBoxReqsAggregatedResponse{
Data: data,
Pagination: kindBoxReqs.Pagination,
}
return c.JSON(http.StatusOK, resp)
}
func getBenefactorIDs(kindBoxReqs []param.Data) []any {
benefactorsMap := make(map[uint]bool)
for _, kindBox := range kindBoxReqs {
benefactorsMap[kindBox.BenefactorID] = true
}
return arrayfunc.MapToSlice(benefactorsMap)
}

View File

@ -1,27 +1,40 @@
package adminkindboxreqhandler
import (
adminaddressaggservice "git.gocasts.ir/ebhomengo/niki/service/admin/address_aggregator"
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
adminbenefactoraggsvc "git.gocasts.ir/ebhomengo/niki/service/admin/benefactor_aggregator"
adminkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/admin/kind_box_req"
adminrefertimeaggregatorservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time_aggregator"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
adminKindBoxReqSvc adminkindboxreqservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
authSvc authservice.Service
adminKindBoxReqSvc adminkindboxreqservice.Service
adminBenefactorAggSvc adminbenefactoraggsvc.Service
addressAggSvc adminaddressaggservice.Service
referTimeAggSvc adminrefertimeaggregatorservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
adminKindBoxReqSvc adminkindboxreqservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service, notificationSvc notification.Service,
adminBenefactorAggSvc adminbenefactoraggsvc.Service,
addressAggSvc adminaddressaggservice.Service,
referTimeAggSvc adminrefertimeaggregatorservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminKindBoxReqSvc: adminKindBoxReqSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
authSvc: authSvc,
adminKindBoxReqSvc: adminKindBoxReqSvc,
adminBenefactorAggSvc: adminBenefactorAggSvc,
addressAggSvc: addressAggSvc,
referTimeAggSvc: referTimeAggSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -13,7 +13,7 @@ import (
// Reject godoc
// @Summary Reject a kindboxreq by admin
// @Tags KindBoxReq
// @Tags Admins KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq id"
@ -21,7 +21,7 @@ import (
// @Success 200 {object} param.KindBoxReqRejectResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/reject-kind-box-req/{id} [patch].
// @Router /admins/kindboxreqs/{id}/reject-kind-box-req [patch].
func (h Handler) Reject(c echo.Context) error {
var req param.KindBoxReqRejectRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -11,13 +11,10 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.Use(middleware.Auth(h.authSvc))
r.POST("", h.AddKindBoxReq, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAddPermission))
r.PATCH("/accept-kind-box-req/:id", h.Accept, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAcceptPermission))
r.PATCH("/reject-kind-box-req/:id", h.Reject, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqRejectPermission))
r.PATCH("/deliver-kind-box-req/:id", h.Deliver, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqDeliverPermission))
r.PATCH("/assign-sender-agent/:id", h.AssignSenderAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAssignSenderAgentPermission))
r.PATCH("/:id/accept-kind-box-req", h.Accept, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAcceptPermission))
r.PATCH("/:id/reject-kind-box-req", h.Reject, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqRejectPermission))
r.PATCH("/:id/assign-sender-agent", h.AssignSenderAgent, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqAssignSenderAgentPermission))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAllPermission))
r.GET("/awaiting-delivery/:id", h.GetAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.GET("/awaiting-delivery", h.GetAllAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.PUT("/:id", h.Update, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqUpdatePermission))
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetPermission))
}

View File

@ -10,7 +10,7 @@ import (
// Update godoc
// @Summary Update kind box request by admin
// @Tags KindBoxReq
// @Tags Admins KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -18,7 +18,7 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/{id} [put].
// @Router /admins/kindboxreqs/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.KindBoxReqUpdateRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -0,0 +1,45 @@
package adminrefertimehandler
import (
"net/http"
refertimeparam "git.gocasts.ir/ebhomengo/niki/param/admin/refer_time"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
echo "github.com/labstack/echo/v4"
)
// GetAll godoc
// @Summary Get all refer times
// @Tags Admins ReferTimes
// @Accept json
// @Produce json
// @Param filter_status query entity.ReferTimeStatus false "Filter by KindBoxReq status" Format(enum)
// @Success 200 {object} adminrefertimeparam.GetAllReferTimeResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admins/refer-times [get].
func (h Handler) GetAll(c echo.Context) error {
var req refertimeparam.GetAllReferTimeRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.Filter = queryparam.GetFilterParams(c)
resp, err := h.adminReferTimeSvc.GetAll(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
if resp.FieldErrors != nil {
return c.JSON(code, httpmsg.ErrorResponse{
Message: msg,
Errors: resp.FieldErrors,
})
}
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -0,0 +1,24 @@
package adminrefertimehandler
import (
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
adminrefertimeservice "git.gocasts.ir/ebhomengo/niki/service/admin/refer_time"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
)
type Handler struct {
authSvc authservice.Service
adminReferTimeSvc adminrefertimeservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
}
func New(authSvc authservice.Service,
adminReferTimeSvc adminrefertimeservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminReferTimeSvc: adminReferTimeSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
}
}

View File

@ -0,0 +1,15 @@
package adminrefertimehandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
echo "github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admins/refer-times")
r.Use(middleware.Auth(h.authSvc))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminReferTimeGetAllPermission))
}

View File

@ -0,0 +1,43 @@
package adminseedhandler
import (
"errors"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
"net/http"
"git.gocasts.ir/ebhomengo/niki/entity"
adminseedparam "git.gocasts.ir/ebhomengo/niki/param/admin/seed"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
echo "github.com/labstack/echo/v4"
)
func (h Handler) Call(c echo.Context) error {
var req adminseedparam.CallSeedRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
var err error
switch req.Action {
case adminseedparam.ActionAddBenefactor:
_, err = h.adminSeedSvc.AddBenefactor(c.Request().Context())
case adminseedparam.AddKindBoxReq:
_, err = h.adminSeedSvc.AddKindBoxReq(c.Request().Context(), entity.KindBoxReqAcceptedStatus)
case adminseedparam.AssignSenderToKindBoxReq:
_, err = h.adminSeedSvc.AssignSenderToKindBoxReq(c.Request().Context(), req.UserId)
case adminseedparam.AddKindBox:
_, err = h.adminSeedSvc.AddKindBox(c.Request().Context(), req.UserId, entity.KindBoxDeliveredStatus)
case adminseedparam.AssignReceiverAgentKindBox:
_, err = h.adminSeedSvc.AssignReceiverAgentKindBox(c.Request().Context(), req.UserId)
default:
err = errors.New(errmsg.ErrorMsgInvalidAction)
}
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusNoContent, "success!")
}

View File

@ -0,0 +1,20 @@
package adminseedhandler
import (
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
adminseederservice "git.gocasts.ir/ebhomengo/niki/service/seeder"
)
type Handler struct {
authSvc authservice.Service
adminSeedSvc adminseederservice.Service
}
func New(authSvc authservice.Service,
adminSeedSvc adminseederservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
adminSeedSvc: adminSeedSvc,
}
}

View File

@ -0,0 +1,14 @@
package adminseedhandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
echo "github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/admins/seed")
r.Use(middleware.Auth(h.authSvc), middleware.TokenSeed(h.authSvc))
r.POST("", h.Call)
}

View File

@ -14,7 +14,7 @@ import (
// GetAll godoc
// @Summary Get all awaiting return KindBoxes by agent
// @Description Retrieves a list of all awaiting return KindBoxes for agent with filtering, sorting, and pagination options
// @Tags KindBox
// @Tags Agents KindBoxes
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
@ -44,8 +44,8 @@ func (h Handler) GetAll(c echo.Context) error {
}
req.Filter = queryparam.GetFilterParams(c)
req.Filter["receiver_agent_id"] = claim.GetClaimsFromEchoContext(c).UserID
req.Filter["status"] = entity.KindBoxAssignedReceiverAgentStatus
req.ReceiverAgentId = claim.GetClaimsFromEchoContext(c).UserID
req.Status = entity.KindBoxAssignedReceiverAgentStatus
resp, err := h.agentKindBoxSvc.GetAll(c.Request().Context(), req)
if err != nil {

View File

@ -11,7 +11,7 @@ import (
// Get godoc
// @Summary Get a kind box that is awaiting return by agent
// @Tags KindBox
// @Tags Agents KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"

View File

@ -4,21 +4,25 @@ import (
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
agentkindboxservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
agentKindBoxSvc agentkindboxservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
agentKindBoxSvc agentkindboxservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
agentKindBoxSvc: agentKindBoxSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -3,6 +3,7 @@ package agentkindboxhandler
import (
"net/http"
params "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
@ -11,7 +12,7 @@ import (
// Return godoc
// @Summary Return KindBox from benefactor by agent
// @Tags KindBox
// @Tags Agents KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -23,7 +24,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerAdmin
// @Router /agents/kindboxes/return/{id} [patch].
// @Router /agents/kindboxes/{id}/return [patch].
func (h Handler) Return(c echo.Context) error {
var req param.ReturnKindBoxRequest
if err := c.Bind(&req); err != nil {
@ -46,5 +47,9 @@ func (h Handler) Return(c echo.Context) error {
return echo.NewHTTPError(code, msg)
}
go h.notificationSvc.KindBoxReturned(params.NotificationKindBoxReturned{
KindBoxID: req.KindBoxID,
})
return c.NoContent(http.StatusNoContent)
}

View File

@ -13,5 +13,5 @@ func (h Handler) SetRoutes(e *echo.Echo) {
r.GET("/:id", h.Get, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetAwaitingReturnPermission))
r.GET("", h.GetAll, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxGetAwaitingReturnPermission))
r.PATCH("/return/:id", h.Return, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReturnPermission))
r.PATCH("/:id/return", h.Return, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReturnPermission))
}

View File

@ -1,10 +1,11 @@
package adminkindboxreqhandler
package agentkindboxreqhandler
import (
"context"
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
params "git.gocasts.ir/ebhomengo/niki/param"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
querier "git.gocasts.ir/ebhomengo/niki/pkg/query_transaction/sql"
@ -12,8 +13,8 @@ import (
)
// Deliver godoc
// @Summary Admin deliver a kindboxreq
// @Tags KindBoxReq
// @Summary Agent deliver a kindboxreq
// @Tags Agents KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -21,7 +22,7 @@ import (
// @Success 200 {object} param.DeliverKindBoxReqResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/deliver-kind-box-req/{id} [patch].
// @Router /agents/kindboxreqs/{id}/deliver-kind-box-req [patch].
func (h Handler) Deliver(c echo.Context) error {
var req param.DeliverKindBoxReqRequest
@ -31,7 +32,7 @@ func (h Handler) Deliver(c echo.Context) error {
q := querier.GetQuerierFromContextOrNew(c.Request().Context()).Begin()
ctx := context.WithValue(c.Request().Context(), querier.QuerierContextKey, q)
resp, sErr := h.adminKindBoxReqSvc.Deliver(ctx, req)
resp, sErr := h.agentKindBoxReqSvc.Deliver(ctx, req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {
@ -52,5 +53,9 @@ func (h Handler) Deliver(c echo.Context) error {
return echo.NewHTTPError(http.StatusInternalServerError, errmsg.ErrorMsgSomethingWentWrong)
}
go h.notificationSvc.KindBoxReqDelivered(params.NotificationKindBoxReqDelivered{
KindBoxReqID: req.KindBoxReqID,
})
return c.JSON(http.StatusOK, resp)
}

View File

@ -1,10 +1,10 @@
package adminkindboxreqhandler
package agentkindboxreqhandler
import (
"net/http"
"git.gocasts.ir/ebhomengo/niki/entity"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
queryparam "git.gocasts.ir/ebhomengo/niki/pkg/query_param"
@ -14,7 +14,7 @@ import (
// GetAllAwaitingDelivery godoc
// @Summary Get all awaiting delivery KindBox requests
// @Description Retrieves a list of all awaiting KindBox requests with filtering, sorting, and pagination options
// @Tags KindBoxReq
// @Tags Agents KindBoxReqs
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
@ -32,7 +32,7 @@ import (
// @Success 200 {object} param.DeliveryAwaitingGetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/awaiting-delivery [get].
// @Router /agents/kindboxreqs/awaiting-delivery [get].
func (h Handler) GetAllAwaitingDelivery(c echo.Context) error {
var req param.DeliveryAwaitingGetAllRequest
@ -40,9 +40,11 @@ func (h Handler) GetAllAwaitingDelivery(c echo.Context) error {
return echo.NewHTTPError(http.StatusBadRequest)
}
req.Filter = queryparam.GetFilterParams(c)
req.Filter["sender_agent_id"] = claim.GetClaimsFromEchoContext(c).UserID
req.Filter["status"] = entity.KindBoxReqAssignedSenderAgentStatus
resp, sErr := h.adminKindBoxReqSvc.GetAllAwaitingDelivery(c.Request().Context(), req)
req.SenderAgentId = claim.GetClaimsFromEchoContext(c).UserID
req.Status = entity.KindBoxReqAssignedSenderAgentStatus
resp, sErr := h.agentKindBoxReqSvc.GetAllAwaitingDelivery(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {

View File

@ -1,9 +1,9 @@
package adminkindboxreqhandler
package agentkindboxreqhandler
import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box_req"
param "git.gocasts.ir/ebhomengo/niki/param/agent/kind_box_req"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
@ -11,14 +11,14 @@ import (
// GetAwaitingDelivery godoc
// @Summary Get a kind box reqs that is awaiting delivery by agent
// @Tags KindBoxReq
// @Tags Agents KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
// @Success 200 {object} param.DeliveryAwaitingGetResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerAdmin
// @Router /admin/kindboxreqs/awaiting-delivery/{id} [get].
// @Router /agents/kindboxreqs/awaiting-delivery/{id} [get].
func (h Handler) GetAwaitingDelivery(c echo.Context) error {
var req param.DeliveryAwaitingGetRequest
if bErr := c.Bind(&req); bErr != nil {
@ -28,7 +28,7 @@ func (h Handler) GetAwaitingDelivery(c echo.Context) error {
claims := claim.GetClaimsFromEchoContext(c)
req.AgentID = claims.UserID
resp, sErr := h.adminKindBoxReqSvc.GetAwaitingDelivery(c.Request().Context(), req)
resp, sErr := h.agentKindBoxReqSvc.GetAwaitingDelivery(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)
if resp.FieldErrors != nil {

View File

@ -0,0 +1,28 @@
package agentkindboxreqhandler
import (
adminauthorizationservice "git.gocasts.ir/ebhomengo/niki/service/admin/authorization"
agentkindboxreqservice "git.gocasts.ir/ebhomengo/niki/service/agent/kind_box_req"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"git.gocasts.ir/ebhomengo/niki/service/notification"
)
type Handler struct {
authSvc authservice.Service
agentKindBoxReqSvc agentkindboxreqservice.Service
adminAuthorizeSvc adminauthorizationservice.Service
notificationSvc notification.Service
}
func New(authSvc authservice.Service,
agentKindBoxReqSvc agentkindboxreqservice.Service,
adminAuthorizeSvc adminauthorizationservice.Service,
notificationSvc notification.Service,
) Handler {
return Handler{
authSvc: authSvc,
agentKindBoxReqSvc: agentKindBoxReqSvc,
adminAuthorizeSvc: adminAuthorizeSvc,
notificationSvc: notificationSvc,
}
}

View File

@ -0,0 +1,16 @@
package agentkindboxreqhandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
"github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/agents/kindboxreqs")
r.Use(middleware.Auth(h.authSvc))
r.GET("/awaiting-delivery/:id", h.GetAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.GET("/awaiting-delivery", h.GetAllAwaitingDelivery, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqGetAwaitingDeliveryPermission))
r.PATCH("/:id/deliver-kind-box-req", h.Deliver, middleware.AdminAuthorization(h.adminAuthorizeSvc, entity.AdminKindBoxReqDeliverPermission))
}

View File

@ -12,14 +12,14 @@ import (
// AddAddress godoc
// @Summary Add a new address for a benefactor
// @Description This endpoint allows an authenticated benefactor to add a new address to their account.
// @Tags Address
// @Tags Benefactors Addresses
// @Accept json
// @Produce json
// @Param Request body param.BenefactorAddAddressRequest true "New address details"
// @Success 201 {object} param.BenefactorAddAddressResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /address/ [post].
// @Security AuthBearerBenefactor
// @Router /benefactors/addresses [post].
func (h Handler) AddAddress(c echo.Context) error {
req := param.BenefactorAddAddressRequest{}
if bErr := c.Bind(&req); bErr != nil {

View File

@ -12,12 +12,12 @@ import (
// DeleteAddress godoc
// @Summary Delete address by benefactor
// @Description This endpoint is used to delete an address by benefactor
// @Tags Address
// @Tags Benefactors Addresses
// @Param id path int true "Address ID"
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /address/{id} [delete].
// @Router /benefactors/addresses/{id} [delete].
func (h Handler) DeleteAddress(c echo.Context) error {
var req param.DeleteAddressRequest

View File

@ -11,14 +11,14 @@ import (
// GetAddress godoc
// @Summary Get a benefactor address
// @Tags Address
// @Tags Benefactors Addresses
// @Accept json
// @Produce json
// @Param id path int true "Address ID"
// @Success 200 {object} param.GetAddressResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /address/{id} [get].
// @Router /benefactors/addresses/{id} [get].
func (h Handler) GetAddress(c echo.Context) error {
var req param.GetAddressRequest
if bErr := echo.PathParamsBinder(c).Uint("id", &req.AddressID).BindError(); bErr != nil {

View File

@ -11,13 +11,13 @@ import (
// GetAddresses godoc
// @Summary Get all benefactor addresses
// @Tags Address
// @Tags Benefactors Addresses
// @Accept json
// @Produce json
// @Success 200 {object} param.GetAllAddressesResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /address/ [get].
// @Router /benefactors/addresses [get].
func (h Handler) GetAddresses(c echo.Context) error {
var req param.GetAllAddressesRequest

View File

@ -10,12 +10,12 @@ import (
// GetAllCities godoc
// @Summary Get all cities
// @Tags Address
// @Tags Benefactors Addresses
// @Accept json
// @Produce json
// @Success 200 {object} addressparam.GetAllCitiesResponse
// @Failure 400 {string} "Bad request"
// @Router /address/cities [get].
// @Router /benefactors/addresses/cities [get].
func (h Handler) GetAllCities(c echo.Context) error {
var req addressparam.GetAllCitiesRequest

View File

@ -10,12 +10,12 @@ import (
// GetAllProvinces godoc
// @Summary Get all provinces
// @Tags Address
// @Tags Benefactors Addresses
// @Accept json
// @Produce json
// @Success 200 {object} addressparam.GetAllProvincesResponse
// @Failure 400 {string} "Bad request"
// @Router /address/provinces [get].
// @Router /benefactors/addresses/provinces [get].
func (h Handler) GetAllProvinces(c echo.Context) error {
var req addressparam.GetAllProvincesRequest

View File

@ -7,18 +7,18 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/address")
r := e.Group("/benefactors/addresses")
r.GET("/provinces", h.GetAllProvinces)
r.GET("/cities", h.GetAllCities)
r.POST("/", h.AddAddress, middleware.Auth(h.authSvc),
r.POST("", h.AddAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.GET("/:id", h.GetAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.GET("/", h.GetAddresses, middleware.Auth(h.authSvc),
r.GET("", h.GetAddresses, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.DELETE("/:id", h.DeleteAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
r.PATCH("/:id", h.UpdateAddress, middleware.Auth(h.authSvc),
r.PUT("/:id", h.UpdateAddress, middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole))
}

View File

@ -10,8 +10,8 @@ import (
)
// UpdateAddress godoc
// @Summary Edit benefactor address
// @Tags Address
// @Summary Update benefactor address
// @Tags Benefactors Addresses
// @Accept json
// @Produce json
// @Param id path int true "Address ID"
@ -19,7 +19,7 @@ import (
// @Success 204
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /address/{id} [patch].
// @Router /benefactors/addresses/{id} [put].
func (h Handler) UpdateAddress(c echo.Context) error {
var req param.UpdateAddressRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -11,13 +11,13 @@ import (
// loginOrRegister godoc
// @Summary Login or register a benefactor
// @Description This endpoint is used to authenticate an existing benefactor account or register a new one.
// @Tags Benefactor
// @Tags Benefactors
// @Accept json
// @Produce json
// @Param Request body benefactoreparam.LoginOrRegisterRequest true "Login or register request details"
// @Success 200 {object} benefactoreparam.LoginOrRegisterResponse
// @Failure 400 {string} "Bad request"
// @Router /benefactor/login-register [post].
// @Router /benefactors/login-register [post].
func (h Handler) loginOrRegister(c echo.Context) error {
var req benefactoreparam.LoginOrRegisterRequest

View File

@ -0,0 +1,36 @@
package benefactorhandler
import (
"net/http"
benefactorparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactor"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// RefreshAccess godoc
// @Summary Get a new access token by providing your refresh token
// @Tags Benefactors
// @Accept json
// @Produce json
// @Param Request body benefactorparam.RefreshAccessRequest true "Refresh access token request body"
// @Success 200 {object} benefactorparam.RefreshAccessResponse
// @Failure 400 {string} "Bad Request"
// @Failure 500 {string} "something went wrong"
// @Router /benefactors/refresh-access [post].
func (h Handler) RefreshAccess(c echo.Context) error {
var req benefactorparam.RefreshAccessRequest
if err := c.Bind(&req); err != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
resp, err := h.benefactorSvc.RefreshAccess(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, resp)
}

View File

@ -5,8 +5,9 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactor")
r := e.Group("/benefactors")
r.POST("/send-otp", h.SendOtp)
r.POST("/login-register", h.loginOrRegister)
r.POST("/refresh-access", h.RefreshAccess)
}

View File

@ -11,13 +11,13 @@ import (
// SendOtp godoc
// @Summary Send OTP to benefactor
// @Description This endpoint sends an OTP to the benefactor's phone number for verification purposes.
// @Tags Benefactor
// @Tags Benefactors
// @Accept json
// @Produce json
// @Param Request body benefactoreparam.SendOtpRequest true "Send OTP request details"
// @Success 200 {object} benefactoreparam.SendOtpResponse
// @Failure 400 {string} "Bad request"
// @Router /benefactor/send-otp [post].
// @Router /benefactors/send-otp [post].
func (h Handler) SendOtp(c echo.Context) error {
var req benefactoreparam.SendOtpRequest

View File

@ -4,6 +4,7 @@ import (
"net/http"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box"
"git.gocasts.ir/ebhomengo/niki/pkg/claim"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
echo "github.com/labstack/echo/v4"
)
@ -11,19 +12,21 @@ import (
// Get godoc
// @Summary Get a specific kind box for a benefactor
// @Description This endpoint retrieves a specific kind box associated with an authenticated benefactor.
// @Tags KindBox
// @Tags Benefactors KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "Kind box ID"
// @Success 200 {object} param.KindBoxGetResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxes/{id} [get].
// @Router /benefactors/kindboxes/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.KindBoxGetRequest
if bErr := c.Bind(&req); bErr != nil {
return echo.NewHTTPError(http.StatusBadRequest)
}
claims := claim.GetClaimsFromEchoContext(c)
req.BenefactorID = claims.UserID
resp, sErr := h.benefactorKindBoxSvc.Get(c.Request().Context(), req)
if sErr != nil {

View File

@ -13,12 +13,11 @@ import (
// GetAll godoc
// @Summary Get all KindBoxes by benefactor
// @Description Retrieves a list of all KindBoxes with filtering, sorting, and pagination options
// @Tags KindBox
// @Tags Benefactors KindBoxes
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
// @Param filter_kind_box_req_id query int false "Filter by KindBox request ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_kind_box_type query string false "Filter by KindBox type" Enums(on-table,cylindrical,stand-up)
// @Param filter_amount query int false "Filter by amount"
// @Param filter_serial_number query string false "Filter by serial number"
@ -40,7 +39,7 @@ import (
// @Success 200 {object} param.KindBoxGetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxes [get].
// @Router /benefactors/kindboxes [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.KindBoxGetAllRequest
@ -49,7 +48,8 @@ func (h Handler) GetAll(c echo.Context) error {
}
req.Filter = queryparam.GetFilterParams(c)
req.Filter["benefactor_id"] = claim.GetClaimsFromEchoContext(c).UserID
req.BenefactorId = claim.GetClaimsFromEchoContext(c).UserID
resp, sErr := h.benefactorKindBoxSvc.GetAll(c.Request().Context(), req)
if sErr != nil {
msg, code := httpmsg.Error(sErr)

View File

@ -12,7 +12,7 @@ import (
// RegisterEmptyingRequest godoc
// @Summary Register a new emptying request for a kind box by benefactor
// @Tags Benefactor
// @Tags Benefactors KindBoxes
// @Accept json
// @Produce json
// @Param id path int true "KindBox ID"
@ -20,7 +20,7 @@ import (
// @Success 204 {string} "No content"
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxes/{id}/emptying-requests [patch].
// @Router /benefactors/kindboxes/{id}/emptying-requests [patch].
func (h Handler) RegisterEmptyingRequest(c echo.Context) error {
var req param.KindBoxRegisterEmptyingRequest
if bErr := c.Bind(&req); bErr != nil {
@ -44,7 +44,7 @@ func (h Handler) RegisterEmptyingRequest(c echo.Context) error {
}
go h.notificationSvc.KindBoxRegisteredEmptyingRequest(params.NotificationKindBoxRegisteredEmptyingRequest{
KindBoxID: resp.ID,
KindBoxID: resp.Data.ID,
})
return c.JSON(http.StatusNoContent, nil)

View File

@ -7,7 +7,7 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactor/kindboxes")
r := e.Group("/benefactors/kindboxes")
r.Use(
middleware.Auth(h.authSvc),

View File

@ -13,14 +13,14 @@ import (
// Add godoc
// @Summary Add a new kind box request for a benefactor
// @Tags KindBoxReq
// @Tags Benefactors KindBoxReqs
// @Accept json
// @Produce json
// @Param Request body param.KindBoxReqAddRequest true "New kind box request details"
// @Success 200 {object} param.KindBoxReqAddResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxreqs/ [post].
// @Router /benefactors/kindboxreqs [post].
func (h Handler) Add(c echo.Context) error {
req := param.KindBoxReqAddRequest{}
if err := c.Bind(&req); err != nil {
@ -46,7 +46,7 @@ func (h Handler) Add(c echo.Context) error {
}
go h.notificationSvc.KindBoxReqAdded(params.NotificationKindBoxReqAdded{
KindBoxReqID: resp.KindBoxReq.ID,
KindBoxReqID: resp.Data.ID,
})
return c.JSON(http.StatusCreated, resp)

View File

@ -9,17 +9,17 @@ import (
"github.com/labstack/echo/v4"
)
// delete godoc
// @Summary delete kindboxreq by benefactor
// Delete godoc
// @Summary Delete kindboxreq by benefactor
// @Description This endpoint is used to delete benefactor's kindboxreq at pending status
// @Tags KindBoxReq
// @Tags Benefactors KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "Kind box request ID"
// @Success 200 {object} param.KindBoxReqDeleteResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxreqs/{id} [delete].
// @Router /benefactors/kindboxreqs/{id} [delete].
func (h Handler) Delete(c echo.Context) error {
req := param.KindBoxReqDeleteRequest{}
if bErr := echo.PathParamsBinder(c).Uint("id", &req.KindBoxReqID).BindError(); bErr != nil {

View File

@ -11,14 +11,14 @@ import (
// Get godoc
// @Summary Get a kind box request for a benefactor
// @Tags KindBoxReq
// @Tags Benefactors KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "Kind box request ID"
// @Success 200 {object} param.KindBoxReqGetResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxreqs/{id} [get].
// @Router /benefactors/kindboxreqs/{id} [get].
func (h Handler) Get(c echo.Context) error {
var req param.KindBoxReqGetRequest
if bErr := echo.PathParamsBinder(c).Uint("id", &req.KindBoxReqID).BindError(); bErr != nil {

View File

@ -13,11 +13,10 @@ import (
// GetAll godoc
// @Summary Get all KindBox requests
// @Description Retrieves a list of all KindBox requests with filtering, sorting, and pagination options
// @Tags KindBoxReq
// @Tags Benefactors KindBoxReqs
// @Accept json
// @Produce json
// @Param filter_id query int false "Filter by ID"
// @Param filter_benefactor_id query int false "Filter by benefactor ID"
// @Param filter_kind_box_type query entity.KindBoxType false "Filter by KindBox type" Format(enum)
// @Param filter_status query string false "Filter by KindBoxReq Status" Enums(pending,accepted,assigned-sender-agent,rejected,delivered)
// @Param filter_count_requested query int false "Filter by count requested"
@ -32,7 +31,7 @@ import (
// @Success 200 {object} param.GetAllResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxreqs/ [get].
// @Router /benefactors/kindboxreqs [get].
func (h Handler) GetAll(c echo.Context) error {
var req param.GetAllRequest
@ -41,7 +40,7 @@ func (h Handler) GetAll(c echo.Context) error {
}
req.Filter = queryparam.GetFilterParams(c)
req.Filter["benefactor_id"] = claim.GetClaimsFromEchoContext(c).UserID
req.BenefactorId = claim.GetClaimsFromEchoContext(c).UserID
resp, sErr := h.benefactorKindBoxReqSvc.GetAll(c.Request().Context(), req)
if sErr != nil {

View File

@ -7,16 +7,16 @@ import (
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactor/kindboxreqs")
r := e.Group("/benefactors/kindboxreqs")
r.Use(
middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole),
)
r.POST("/", h.Add)
r.POST("", h.Add)
r.GET("/:id", h.Get)
r.DELETE("/:id", h.Delete)
r.GET("/", h.GetAll)
r.GET("", h.GetAll)
r.PUT("/:id", h.Update)
}

View File

@ -11,7 +11,7 @@ import (
// Update godoc
// @Summary Update kind box request by benefactor
// @Tags KindBoxReq
// @Tags Benefactors KindBoxReqs
// @Accept json
// @Produce json
// @Param id path int true "KindBoxReq ID"
@ -23,7 +23,7 @@ import (
// @Failure 422 {object} httpmsg.ErrorResponse
// @Failure 500 {string} "something went wrong"
// @Security AuthBearerBenefactor
// @Router /benefactor/kindboxreqs/{id} [put].
// @Router /benefactors/kindboxreqs/{id} [put].
func (h Handler) Update(c echo.Context) error {
var req param.KindBoxReqUpdateRequest
if bErr := c.Bind(&req); bErr != nil {

View File

@ -0,0 +1,31 @@
package benefactorrefertimehandler
import (
"net/http"
refertimeparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/refer_time"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/labstack/echo/v4"
)
// GetAll godoc
// @Summary Get all refer times
// @Tags Benefactors ReferTimes
// @Accept json
// @Produce json
// @Success 200 {object} benefactorrefertimeparam.GetAllReferTimeResponse
// @Failure 400 {string} "Bad request"
// @Security AuthBearerBenefactor
// @Router /benefactors/refer-times [get].
func (h Handler) GetAll(c echo.Context) error {
var req refertimeparam.GetAllReferTimeRequest
listReferTimes, err := h.benefactorReferTimeSvc.GetAll(c.Request().Context(), req)
if err != nil {
msg, code := httpmsg.Error(err)
return echo.NewHTTPError(code, msg)
}
return c.JSON(http.StatusOK, listReferTimes)
}

View File

@ -0,0 +1,20 @@
package benefactorrefertimehandler
import (
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
benefactorrefertimeservice "git.gocasts.ir/ebhomengo/niki/service/benefactor/refer_time"
)
type Handler struct {
authSvc authservice.Service
benefactorReferTimeSvc benefactorrefertimeservice.Service
}
func New(authSvc authservice.Service,
benefactorReferTimeSvc benefactorrefertimeservice.Service,
) Handler {
return Handler{
authSvc: authSvc,
benefactorReferTimeSvc: benefactorReferTimeSvc,
}
}

View File

@ -0,0 +1,18 @@
package benefactorrefertimehandler
import (
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/middleware"
"git.gocasts.ir/ebhomengo/niki/entity"
"github.com/labstack/echo/v4"
)
func (h Handler) SetRoutes(e *echo.Echo) {
r := e.Group("/benefactors/refer-times")
r.Use(
middleware.Auth(h.authSvc),
middleware.BenefactorAuthorization(entity.UserBenefactorRole),
)
r.GET("", h.GetAll)
}

View File

@ -0,0 +1,43 @@
//go:build end2end
// +build end2end
package end2end
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)
func TestAdmin_KindBox_Get(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
// Get token
lRes, err := services.AdminSvc.LoginWithPhoneNumber(context.Background(), adminserviceparam.LoginWithPhoneNumberRequest{
PhoneNumber: "09384664402",
Password: "Abc123456",
})
if err != nil {
t.Fatalf("could not login: %s", err)
}
// Create a request
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes/1", nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
// Serve the request
testServer.Serve(rec, req)
// Assertions
assert.Equal(t, http.StatusOK, rec.Code)
}

View File

@ -1,194 +0,0 @@
//go:build end2end
// +build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
adminserviceparam "git.gocasts.ir/ebhomengo/niki/param/admin/admin"
param "git.gocasts.ir/ebhomengo/niki/param/admin/kind_box"
"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)
// Utility function to log in as an admin with dynamic credentials
func loginAsAdmin(t *testing.T, phoneNumber, password string) (*adminserviceparam.LoginWithPhoneNumberResponse, error) {
lRes, err := services.AdminSvc.LoginWithPhoneNumber(context.Background(), adminserviceparam.LoginWithPhoneNumberRequest{
PhoneNumber: phoneNumber,
Password: password,
})
if err != nil {
t.Fatalf("could not login: %s", err)
return nil, err
}
return &lRes, nil // Return address of lRes
}
func TestAdmin_KindBox_Enumerate(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{
"amount": 5
}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/1/enumerate", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusNoContent, rec.Code)
}
func TestAdmin_KindBox_Enumerate_MissingAmount(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/1/enumerate", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusUnprocessableEntity, rec.Code)
}
func TestAdmin_KindBox_Enumerate_NegativeAmount(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{
"amount": -5
}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/1/enumerate", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusBadRequest, rec.Code)
}
func TestAdmin_KindBox_Enumeration_Forbidden(t *testing.T) {
lRes, err := loginAsAdmin(t, "09384664403", "Abc123456")
if err != nil {
return
}
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes/1/enumerate", nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusForbidden, rec.Code)
var response httpmsg.ErrorResponse
err = json.NewDecoder(rec.Body).Decode(&response)
if err != nil {
t.Fatalf("could not decode response: %s", err)
}
}
func TestAdmin_KindBox_GetAll(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes?page_number=1&page_size=10&sort=created_at&order=desc&filter=status:active", nil)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
var response param.KindBoxGetAllResponse
err = json.NewDecoder(rec.Body).Decode(&response)
if err != nil {
t.Fatalf("could not decode response: %s", err)
}
assert.NotEmpty(t, response.AllKindBox, "expected kind boxes in response")
assert.Equal(t, uint(1), response.Pagination.PageNumber, "expected page 1")
assert.Equal(t, uint(10), response.Pagination.PageSize, "expected limit 10")
assert.Empty(t, response.FieldErrors, "expected no field errors")
}
func TestAdmin_KindBox_AssignReceiver(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
reqBody := `{
"receiver_agent_id": 4
}`
req := httptest.NewRequest(http.MethodPatch, "/admin/kindboxes/assign-receiver-agent/1", strings.NewReader(reqBody))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusUnprocessableEntity, rec.Code)
}
func TestAdmin_KindBox_Get(t *testing.T) {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
t.Cleanup(teardown)
lRes, err := loginAsAdmin(t, "09384664401", "Abc123456")
if err != nil {
return
}
req := httptest.NewRequest(http.MethodGet, "/admin/kindboxes/1", nil)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", lRes.Tokens.AccessToken))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
}

View File

@ -0,0 +1,193 @@
//go:build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
addressparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/address"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/stretchr/testify/suite"
)
type BenefactorAddressTestSuit struct {
suite.Suite
benefactorPhone string
benefactorID uint
addressID uint
getAllExpected map[string]interface{}
getExpected addressparam.GetAddressResponse
createData addressparam.BenefactorAddAddressRequest
updateData addressparam.UpdateAddressRequest
teardown func()
}
func TestBenefactorAddressTestSuit(t *testing.T) {
suite.Run(t, new(BenefactorAddressTestSuit))
}
// SetupTest runs before each test in the suite
func (suite *BenefactorAddressTestSuit) SetupTest() {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
suite.T().Cleanup(teardown)
suite.benefactorPhone = "09384664404"
suite.benefactorID = 1
suite.addressID = 1
suite.getAllExpected = map[string]interface{}{
"count": 1,
}
suite.createData = addressparam.BenefactorAddAddressRequest{
PostalCode: "3719655861",
Address: "create shiraz kaf sharo",
Lat: 29.62949,
Lon: 52.497287,
CityID: 194,
Name: "create shiraz",
}
suite.updateData = addressparam.UpdateAddressRequest{
PostalCode: "3719655861",
Address: "update shiraz kaf sharo",
Lat: 29.62949,
Lon: 52.497287,
CityID: 194,
Name: "update shiraz",
}
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressGet() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses/%d", suite.addressID)
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response addressparam.GetAddressResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
address, sErr := services.BenefactorAddressSvc.Get(context.Background(),
addressparam.GetAddressRequest{
AddressID: suite.addressID,
BenefactorID: suite.benefactorID,
})
suite.Require().NoError(sErr, "failed to get benefactor address")
suite.Require().Equal(address.Data.PostalCode, response.Data.PostalCode)
suite.Require().Equal(address.Data.Address, response.Data.Address)
suite.Require().Equal(address.Data.Name, response.Data.Name)
suite.Require().Equal(address.Data.CityID, response.Data.CityID)
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, "", nil) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressGetAll() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses")
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response addressparam.GetAllAddressesResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
suite.Require().Equal(suite.getAllExpected["count"], len(response.Data))
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("GET", url, "", nil) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressCreate() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses")
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("POST", url, token, suite.createData)
suite.Require().Equal(http.StatusCreated, responseRecord.Code)
var response addressparam.BenefactorAddAddressResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
suite.Require().Equal(suite.benefactorID, response.Data.BenefactorID)
suite.Require().Equal(suite.createData.Address, response.Data.Address)
suite.Require().Equal(suite.createData.PostalCode, response.Data.PostalCode)
suite.Require().Equal(suite.createData.Name, response.Data.Name)
suite.Require().Equal(suite.createData.CityID, response.Data.CityID)
})
suite.T().Run("Failure_BadRequest", func(t *testing.T) {
responseRecord := CreateRequest("POST", url, token, nil) // No data provided
suite.Require().Equal(http.StatusUnprocessableEntity, responseRecord.Code)
})
}
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressUpdate() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses/%d", suite.addressID)
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("PUT", url, token, suite.updateData)
suite.Require().Equal(http.StatusNoContent, responseRecord.Code)
updatedAddress, sErr := services.BenefactorAddressSvc.Get(context.Background(),
addressparam.GetAddressRequest{
AddressID: suite.addressID,
BenefactorID: suite.benefactorID,
})
suite.Require().NoError(sErr, "failed to get benefactor address")
suite.Require().Equal(suite.updateData.PostalCode, updatedAddress.Data.PostalCode)
suite.Require().Equal(suite.updateData.Address, updatedAddress.Data.Address)
suite.Require().Equal(suite.updateData.Name, updatedAddress.Data.Name)
suite.Require().Equal(suite.updateData.CityID, updatedAddress.Data.CityID)
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("PUT", url, "", suite.updateData) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
// TestBenefactorAddressDelete tests the DELETE /address/:id endpoint
func (suite *BenefactorAddressTestSuit) TestBenefactorAddressDelete() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/addresses/%d", suite.addressID)
suite.T().Run("Success", func(t *testing.T) {
responseRecord := CreateRequest("DELETE", url, token, nil)
suite.Require().Equal(http.StatusNoContent, responseRecord.Code)
_, err := services.BenefactorAddressSvc.Get(context.Background(),
addressparam.GetAddressRequest{
AddressID: suite.addressID,
BenefactorID: suite.benefactorID,
},
)
message, code := httpmsg.Error(err)
suite.Require().Error(err)
suite.Equal(http.StatusNotFound, code)
suite.Equal(errmsg.ErrorMsgNotFound, message)
})
suite.T().Run("Failure_Unauthorized", func(t *testing.T) {
responseRecord := CreateRequest("DELETE", url, "", nil) // No token provided
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}

View File

@ -0,0 +1,104 @@
//go:build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
benefactorkindboxparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box"
"github.com/stretchr/testify/suite"
)
type BenefactorKindBoxTestSuite struct {
suite.Suite
benefactorPhone string
benefactorID uint
kindBoxID uint
kindBboxGetAllExpected map[string]interface{}
kindBoxGetExpected benefactorkindboxparam.KindBoxGetResponse
}
func TestBenefactorKindBoxTestSuite(t *testing.T) {
suite.Run(t, new(BenefactorKindBoxTestSuite))
}
func (suite *BenefactorKindBoxTestSuite) SetupTest() {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
suite.T().Cleanup(teardown)
suite.benefactorPhone = "09384664404"
suite.benefactorID = 1
suite.kindBoxID = 1
suite.kindBboxGetAllExpected = map[string]interface{}{
"count": 1,
}
}
// Test for GET /benefactor/kindboxes (Get All Kind Boxes)
func (suite *BenefactorKindBoxTestSuite) TestBenefactorKindBoxGetAll() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxes")
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxparam.KindBoxGetAllResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response")
suite.Require().Equal(suite.kindBboxGetAllExpected["count"], len(response.Data))
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxes")
responseRecord := CreateRequest("GET", url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
// Test for GET /benefactor/kindboxes/:id (Get Single Kind Box)
func (suite *BenefactorKindBoxTestSuite) TestBenefactorKindBoxGet() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxes/%d", suite.kindBoxID)
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxparam.KindBoxGetResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "could not decode response body")
kindBox, sErr := services.BenefactorKindBoxSvc.Get(context.Background(),
benefactorkindboxparam.KindBoxGetRequest{
BenefactorID: suite.benefactorID,
KindBoxID: suite.kindBoxID,
})
suite.Require().NoError(sErr, "failed to get benefactor kind box")
suite.Require().Equal(kindBox.Data.ID, response.Data.ID)
suite.Require().Equal(kindBox.Data.KindBoxReqID, response.Data.KindBoxReqID)
suite.Require().Equal(kindBox.Data.BenefactorID, response.Data.BenefactorID)
suite.Require().Equal(kindBox.Data.KindBoxType, response.Data.KindBoxType)
suite.Require().Equal(kindBox.Data.Amount, response.Data.Amount)
suite.Require().Equal(kindBox.Data.SerialNumber, response.Data.SerialNumber)
suite.Require().Equal(kindBox.Data.Status, response.Data.Status)
suite.Require().Equal(kindBox.Data.DeliverReferTimeID, response.Data.DeliverReferTimeID)
suite.Require().Equal(kindBox.Data.DeliverReferDate, response.Data.DeliverReferDate)
})
suite.Run("Failure_NotFound", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxes/%d", 9999) // Non-existent ID
responseRecord := CreateRequest("GET", url, token, nil)
suite.Require().Equal(http.StatusUnprocessableEntity, responseRecord.Code)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxes/%d", suite.kindBoxID)
responseRecord := CreateRequest("GET", url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}

View File

@ -0,0 +1,206 @@
//go:build end2end
package end2end
import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"
"time"
"git.gocasts.ir/ebhomengo/niki/delivery/http_server/end2end/setup"
"git.gocasts.ir/ebhomengo/niki/entity"
benefactorkindboxreqparam "git.gocasts.ir/ebhomengo/niki/param/benefactor/kind_box_req"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
httpmsg "git.gocasts.ir/ebhomengo/niki/pkg/http_msg"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type BenefactorKindBoxReqsTestSuite struct {
suite.Suite
benefactorPhone string
benefactorID uint
kindBoxReqID uint
getAllExpected map[string]interface{}
createData benefactorkindboxreqparam.KindBoxReqAddRequest
updateData benefactorkindboxreqparam.KindBoxReqUpdateRequest
}
func TestBenefactorKindBoxReqsTestSuite(t *testing.T) {
suite.Run(t, new(BenefactorKindBoxReqsTestSuite))
}
func (suite *BenefactorKindBoxReqsTestSuite) SetupTest() {
teardown := setup.SeedMariaDB(testContainer.GetMariaDBConfig())
suite.T().Cleanup(teardown)
suite.benefactorPhone = "09384664404"
suite.benefactorID = uint(1)
suite.kindBoxReqID = uint(1)
suite.getAllExpected = map[string]interface{}{
"count": 5,
}
suite.createData = benefactorkindboxreqparam.KindBoxReqAddRequest{
KindBoxType: entity.KindBoxCylindrical,
DeliverAddressID: uint(1),
DeliverReferDate: time.Now().AddDate(0, 0, 7).UTC(),
DeliverReferTimeID: uint(1),
CountRequested: uint(5),
}
suite.updateData = benefactorkindboxreqparam.KindBoxReqUpdateRequest{
KindBoxType: entity.KindBoxCylindrical,
CountRequested: uint(10),
Description: "updated description",
DeliverReferTimeID: uint(1),
DeliverReferDate: time.Now().AddDate(0, 0, 7).UTC(),
DeliverAddressID: uint(1),
}
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_GetAll_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs")
responseRecord := CreateRequest(http.MethodGet, url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxreqparam.GetAllResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "failed to decode response body")
assert.Equal(suite.T(), suite.getAllExpected["count"], len(response.Data))
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs")
responseRecord := CreateRequest(http.MethodGet, url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Get_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
responseRecord := CreateRequest(http.MethodGet, url, token, nil)
suite.Require().Equal(http.StatusOK, responseRecord.Code)
var response benefactorkindboxreqparam.KindBoxReqGetResponse
err := json.NewDecoder(responseRecord.Body).Decode(&response)
suite.Require().NoError(err, "failed to decode response body")
kinBoxReq, err := services.BenefactorKindBoxReqSvc.Get(context.Background(),
benefactorkindboxreqparam.KindBoxReqGetRequest{
BenefactorID: suite.benefactorID,
KindBoxReqID: suite.kindBoxReqID,
})
suite.Require().NoError(err, "failed to get kind box request")
assert.Equal(suite.T(), kinBoxReq.Data.KindBoxType, response.Data.KindBoxType)
assert.Equal(suite.T(), kinBoxReq.Data.CountRequested, response.Data.CountRequested)
assert.Equal(suite.T(), kinBoxReq.Data.Description, response.Data.Description)
assert.Equal(suite.T(), kinBoxReq.Data.DeliverReferTimeID, response.Data.DeliverReferTimeID)
})
suite.Run("Failure_NotFound", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", 9999) // Non-existent ID
responseRecord := CreateRequest(http.MethodGet, url, token, nil)
suite.Require().Equal(http.StatusNotFound, responseRecord.Code)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
responseRecord := CreateRequest(http.MethodGet, url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, responseRecord.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Create_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs")
rec := CreateRequest(http.MethodPost, url, token, suite.createData)
suite.Require().Equal(http.StatusCreated, rec.Code)
var response benefactorkindboxreqparam.KindBoxReqAddResponse
err := json.NewDecoder(rec.Body).Decode(&response)
suite.Require().NoError(err, "failed to decode response body")
assert.Equal(suite.T(), suite.createData.KindBoxType, response.Data.KindBoxType)
assert.Equal(suite.T(), suite.createData.DeliverAddressID, response.Data.DeliverAddressID)
assert.Equal(suite.T(), suite.createData.DeliverReferDate, response.Data.DeliverReferDate)
assert.Equal(suite.T(), suite.createData.CountRequested, response.Data.CountRequested)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs")
rec := CreateRequest(http.MethodPost, url, "invalid_token", suite.createData)
suite.Require().Equal(http.StatusUnauthorized, rec.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Update_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodPut, url, token, suite.updateData)
suite.Require().Equal(http.StatusNoContent, rec.Code)
kindBoxReq, err := services.BenefactorKindBoxReqSvc.Get(context.Background(),
benefactorkindboxreqparam.KindBoxReqGetRequest{
BenefactorID: suite.benefactorID,
KindBoxReqID: suite.kindBoxReqID,
},
)
suite.Require().NoError(err, "failed to get kind box request")
assert.Equal(suite.T(), suite.updateData.CountRequested, kindBoxReq.Data.CountRequested)
assert.Equal(suite.T(), suite.updateData.Description, kindBoxReq.Data.Description)
assert.Equal(suite.T(), suite.updateData.DeliverReferTimeID, kindBoxReq.Data.DeliverReferTimeID)
assert.Equal(
suite.T(),
suite.updateData.DeliverReferDate.Format("2006-01-02"),
kindBoxReq.Data.DeliverReferDate.Format("2006-01-02"),
)
assert.Equal(suite.T(), suite.updateData.DeliverAddressID, kindBoxReq.Data.DeliverAddressID)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodPut, url, "invalid_token", suite.updateData)
suite.Require().Equal(http.StatusUnauthorized, rec.Code)
})
}
func (suite *BenefactorKindBoxReqsTestSuite) TestBenefactorKindBoxReqs_Delete_Success() {
suite.Run("Success", func() {
token := LoginBenefactor(suite.benefactorPhone)
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodDelete, url, token, nil)
suite.Require().Equal(http.StatusOK, rec.Code)
_, err := services.BenefactorKindBoxReqSvc.Get(context.Background(),
benefactorkindboxreqparam.KindBoxReqGetRequest{
BenefactorID: suite.benefactorID,
KindBoxReqID: suite.kindBoxReqID,
},
)
message, code := httpmsg.Error(err)
suite.Require().Error(err)
assert.Equal(suite.T(), http.StatusNotFound, code)
assert.Equal(suite.T(), errmsg.ErrorMsgNotFound, message)
})
suite.Run("Failure_Unauthorized", func() {
url := fmt.Sprintf("/benefactors/kindboxreqs/%d", suite.kindBoxReqID)
rec := CreateRequest(http.MethodDelete, url, "invalid_token", nil)
suite.Require().Equal(http.StatusUnauthorized, rec.Code)
})
}

View File

@ -0,0 +1,54 @@
//go:build end2end
package end2end
import (
"bytes"
"context"
"encoding/json"
"fmt"
"log"
"net/http/httptest"
param "git.gocasts.ir/ebhomengo/niki/param/benefactor/benefactor"
"github.com/labstack/echo/v4"
)
// CreateRequest is a utility function to create and send HTTP requests
func CreateRequest(method, url, token string, body interface{}) *httptest.ResponseRecorder {
var buf bytes.Buffer
if body != nil {
err := json.NewEncoder(&buf).Encode(body)
if err != nil {
log.Fatalf("could not encode body: %v", err)
}
}
req := httptest.NewRequest(method, url, &buf)
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, fmt.Sprintf("Bearer %s", token))
rec := httptest.NewRecorder()
testServer.Serve(rec, req)
return rec
}
// LoginBenefactor is a utility function to login a benefactor and return the access token
func LoginBenefactor(phoneNumber string) string {
sendOTPRes, err := services.BenefactorSvc.SendOtp(context.Background(), param.SendOtpRequest{
PhoneNumber: phoneNumber,
})
if err != nil {
log.Fatalf("failed to send OTP: %v", err)
}
registerRes, err := services.BenefactorSvc.LoginOrRegister(context.Background(), param.LoginOrRegisterRequest{
PhoneNumber: phoneNumber,
VerificationCode: sendOTPRes.Code,
})
if err != nil {
log.Fatalf("failed to register: %v", err)
}
return registerRes.Tokens.AccessToken
}

View File

@ -1,12 +1,12 @@
package setup
import (
"github.com/labstack/echo/v4"
"net/http"
"git.gocasts.ir/ebhomengo/niki/config"
httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
"git.gocasts.ir/ebhomengo/niki/service"
"github.com/labstack/echo/v4"
)
type TestServer struct {

View File

@ -14,7 +14,7 @@ func Auth(service authservice.Service) echo.MiddlewareFunc {
// TODO - as sign method string to config
SigningMethod: "HS256",
ParseTokenFunc: func(c echo.Context, auth string) (interface{}, error) {
claims, err := service.ParseToken(auth)
claims, err := service.ParseBearerToken(auth)
if err != nil {
return nil, err
}

View File

@ -9,7 +9,7 @@ import (
"github.com/labstack/echo/v4"
)
//nolint
// nolint
func BenefactorAuthorization(role entity.UserRole) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {

View File

@ -0,0 +1,23 @@
package middleware
import (
"net/http"
errmsg "git.gocasts.ir/ebhomengo/niki/pkg/err_msg"
authservice "git.gocasts.ir/ebhomengo/niki/service/auth"
"github.com/labstack/echo/v4"
)
// nolint
func TokenSeed(cfg authservice.Service) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
token := c.Request().Header.Get("token")
if token != cfg.Config.SeedToken {
return c.JSON(http.StatusForbidden, echo.Map{"message": errmsg.ErrorMsgUserNotAllowed})
}
return next(c)
}
}
}

View File

@ -6,13 +6,18 @@ import (
"git.gocasts.ir/ebhomengo/niki/config"
adminhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/admin"
adminagenthandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/agent"
adminbenefactorhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/benefactor"
adminKindBoxHandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/kind_box"
adminkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/kind_box_req"
adminrefertimehandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/refer_time"
adminseedhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/admin/seed"
agentkindboxhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/agent/kind_box"
agentkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/agent/kind_box_req"
benefactoraddresshandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/address"
benefactorhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/benefactor"
benefactorkindboxhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/kind_box"
benefactorkindboxreqhandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/kind_box_req"
benefactorrefertimehandler "git.gocasts.ir/ebhomengo/niki/delivery/http_server/benefactor/refer_time"
"git.gocasts.ir/ebhomengo/niki/docs"
"git.gocasts.ir/ebhomengo/niki/service"
echo "github.com/labstack/echo/v4"
@ -27,11 +32,16 @@ type Server struct {
adminKindBoxReqHandler adminkindboxreqhandler.Handler
adminKindBoxHandler adminKindBoxHandler.Handler
adminAgentHandler adminagenthandler.Handler
adminBenefactorHandler adminbenefactorhandler.Handler
adminReferTimeHandler adminrefertimehandler.Handler
agentKindBoxHandler agentkindboxhandler.Handler
agentKindBoxReqHandler agentkindboxreqhandler.Handler
benefactorHandler benefactorhandler.Handler
benefactorKindBoxReqHandler benefactorkindboxreqhandler.Handler
benefactorAddressHandler benefactoraddresshandler.Handler
benefactorKindBoxHandler benefactorkindboxhandler.Handler
benefactorReferTimeHandler benefactorrefertimehandler.Handler
adminSeedHandler adminseedhandler.Handler
}
func New(
@ -42,14 +52,19 @@ func New(
Router: echo.New(),
config: cfg,
adminHandler: adminhandler.New(svc.AdminAuthSvc, svc.AdminSvc, svc.AdminAuthorizeSvc),
adminKindBoxReqHandler: adminkindboxreqhandler.New(svc.AdminAuthSvc, svc.AdminKindBoxReqSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminKindBoxHandler: adminKindBoxHandler.New(svc.AdminAuthSvc, svc.AdminKindBoxSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminKindBoxReqHandler: adminkindboxreqhandler.New(svc.AdminAuthSvc, svc.AdminKindBoxReqSvc, svc.AdminBenefactorAggSvc, svc.AdminAddressAggSvc, svc.AdminReferTimeAggSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminKindBoxHandler: adminKindBoxHandler.New(svc.AdminAuthSvc, svc.AdminKindBoxSvc, svc.AdminBenefactorAggSvc, svc.AdminAddressAggSvc, svc.AdminReferTimeAggSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
adminAgentHandler: adminagenthandler.New(svc.AdminAuthSvc, svc.AdminAgentSvc, svc.AdminAuthorizeSvc),
agentKindBoxHandler: agentkindboxhandler.New(svc.AdminAuthSvc, svc.AgentKindBoxSvc, svc.AdminAuthorizeSvc),
adminBenefactorHandler: adminbenefactorhandler.New(svc.AdminAuthSvc, svc.AdminAuthorizeSvc, svc.AdminBenefactorSvc, svc.AdminAddressSvc, svc.AdminKindBoxSvc, svc.AdminKindBoxReqSvc),
adminReferTimeHandler: adminrefertimehandler.New(svc.AdminAuthSvc, svc.AdminReferTimeSvc, svc.AdminAuthorizeSvc),
adminSeedHandler: adminseedhandler.New(svc.AdminAuthSvc, svc.AdminSeedSvc),
agentKindBoxHandler: agentkindboxhandler.New(svc.AdminAuthSvc, svc.AgentKindBoxSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
agentKindBoxReqHandler: agentkindboxreqhandler.New(svc.AdminAuthSvc, svc.AgentKindBoxReqSvc, svc.AdminAuthorizeSvc, svc.NotificationSvc),
benefactorHandler: benefactorhandler.New(svc.BenefactorAuthSvc, svc.BenefactorSvc),
benefactorKindBoxReqHandler: benefactorkindboxreqhandler.New(svc.BenefactorAuthSvc, svc.BenefactorKindBoxReqSvc, svc.NotificationSvc),
benefactorAddressHandler: benefactoraddresshandler.New(svc.BenefactorAuthSvc, svc.BenefactorAddressSvc),
benefactorKindBoxHandler: benefactorkindboxhandler.New(svc.BenefactorAuthSvc, svc.BenefactorKindBoxSvc, svc.NotificationSvc),
benefactorReferTimeHandler: benefactorrefertimehandler.New(svc.BenefactorAuthSvc, svc.BenefactorReferTimeSvc),
}
}
@ -67,7 +82,10 @@ func (s Server) Serve() {
func (s Server) RegisterRoutes() {
s.Router.Use(middleware.RequestID())
s.Router.Use(middleware.Recover())
registerSwagger(s.Router, s.config)
s.Router.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: s.config.HTTPServer.Cors.AllowOrigins,
}))
registerSwagger(s.Router)
// Routes
s.Router.GET("/health-check", s.healthCheck)
@ -75,18 +93,23 @@ func (s Server) RegisterRoutes() {
s.benefactorKindBoxReqHandler.SetRoutes(s.Router)
s.benefactorAddressHandler.SetRoutes(s.Router)
s.benefactorKindBoxHandler.SetRoutes(s.Router)
s.benefactorReferTimeHandler.SetRoutes(s.Router)
s.adminHandler.SetRoutes(s.Router)
s.adminAgentHandler.SetRoutes(s.Router)
s.adminKindBoxReqHandler.SetRoutes(s.Router)
s.adminKindBoxHandler.SetRoutes(s.Router)
s.adminReferTimeHandler.SetRoutes(s.Router)
s.adminBenefactorHandler.SetRoutes(s.Router)
s.agentKindBoxHandler.SetRoutes(s.Router)
s.agentKindBoxReqHandler.SetRoutes(s.Router)
s.adminSeedHandler.SetRoutes(s.Router)
}
func registerSwagger(s *echo.Echo, c config.Config) {
func registerSwagger(s *echo.Echo) {
// TODO: move this to a better place and make it more dynamic and configurable
docs.SwaggerInfo.Title = "NIKI API"
docs.SwaggerInfo.Description = "This is the API documentation for the NIKI project"
docs.SwaggerInfo.Version = "1.0.0"
docs.SwaggerInfo.Host = fmt.Sprintf("localhost:%d", c.HTTPServer.Port)
s.GET("/swagger/*any", echoSwagger.WrapHandler)
}

Some files were not shown because too many files have changed in this diff Show More