Skip to content

Commit b9c0e98

Browse files
committed
PR-fixes
1 parent 4b18a97 commit b9c0e98

File tree

5 files changed

+302
-252
lines changed

5 files changed

+302
-252
lines changed

core/src/adapters/communication-adapter.ts

Lines changed: 12 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -239,27 +239,16 @@ export const sendBulkSms = async ({
239239
text,
240240
}: BulkSms): Promise<AdapterResult<BulkSmsResult, 'error'>> => {
241241
try {
242-
const axiosOptions = {
243-
method: 'POST',
244-
headers: {
245-
'Content-type': 'application/json',
246-
},
247-
}
248-
249-
const result = await axios(
242+
const result = await axios.post(
250243
`${config.communicationService.url}/sendBulkSms`,
251-
{
252-
...axiosOptions,
253-
data: { phoneNumbers, text },
254-
}
244+
{ phoneNumbers, text }
255245
)
256246

257-
if (result.status !== 200) {
258-
return { ok: false, err: 'error', statusCode: result.status }
259-
}
260-
261247
return { ok: true, data: result.data.content }
262-
} catch {
248+
} catch (err) {
249+
if (axios.isAxiosError(err) && err.response) {
250+
return { ok: false, err: 'error', statusCode: err.response.status }
251+
}
263252
return { ok: false, err: 'error', statusCode: 500 }
264253
}
265254
}
@@ -270,27 +259,16 @@ export const sendBulkEmail = async ({
270259
text,
271260
}: BulkEmail): Promise<AdapterResult<BulkEmailResult, 'error'>> => {
272261
try {
273-
const axiosOptions = {
274-
method: 'POST',
275-
headers: {
276-
'Content-type': 'application/json',
277-
},
278-
}
279-
280-
const result = await axios(
262+
const result = await axios.post(
281263
`${config.communicationService.url}/sendBulkEmail`,
282-
{
283-
...axiosOptions,
284-
data: { emails, subject, text },
285-
}
264+
{ emails, subject, text }
286265
)
287266

288-
if (result.status !== 200) {
289-
return { ok: false, err: 'error', statusCode: result.status }
290-
}
291-
292267
return { ok: true, data: result.data.content }
293-
} catch {
268+
} catch (err) {
269+
if (axios.isAxiosError(err) && err.response) {
270+
return { ok: false, err: 'error', statusCode: err.response.status }
271+
}
294272
return { ok: false, err: 'error', statusCode: 500 }
295273
}
296274
}

core/src/adapters/leasing-adapter/index.ts

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -891,23 +891,23 @@ const deleteListingTextContent = async (
891891

892892
const getContactsByFilters = async (
893893
queryParams: Record<string, string | string[] | undefined>
894-
): Promise<{ content: leasing.v1.ContactInfo[] }> => {
895-
const params = new URLSearchParams()
896-
897-
Object.entries(queryParams).forEach(([key, value]) => {
898-
if (value === undefined) return
899-
if (Array.isArray(value)) {
900-
value.forEach((v) => params.append(key, v))
901-
} else {
902-
params.append(key, value)
903-
}
904-
})
905-
906-
const response = await axios.get(
907-
`${tenantsLeasesServiceUrl}/leases/contacts-by-filters?${params.toString()}`
908-
)
894+
): Promise<AdapterResult<{ content: leasing.v1.ContactInfo[] }, 'unknown'>> => {
895+
try {
896+
const response = await axios.get(
897+
`${tenantsLeasesServiceUrl}/leases/contacts-by-filters`,
898+
{
899+
params: queryParams,
900+
paramsSerializer: {
901+
indexes: null,
902+
},
903+
}
904+
)
909905

910-
return response.data
906+
return { ok: true, data: response.data }
907+
} catch (err) {
908+
logger.error({ err }, 'leasingAdapter.getContactsByFilters')
909+
return { ok: false, err: 'unknown' }
910+
}
911911
}
912912

913913
interface ExportLeasesResult {
@@ -934,7 +934,7 @@ const exportLeasesToExcel = async (
934934
return {
935935
ok: true,
936936
data: {
937-
data: Buffer.from(response.data),
937+
data: response.data,
938938
contentType:
939939
response.headers['content-type'] ||
940940
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',

core/src/api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { routes as propertyBaseRoutes } from './services/property-base-service'
66
import { routes as searchRoutes } from './services/search-service'
77
import { routes as economyRoutes } from './services/economy-service'
88
import { routes as fileStorageRoutes } from './services/file-storage-service'
9+
import { routes as communicationRoutes } from './services/communication-service'
910

1011
import { updateSwaggerSchemas } from './swagger'
1112

@@ -19,6 +20,7 @@ propertyBaseRoutes(router)
1920
searchRoutes(router)
2021
economyRoutes(router)
2122
fileStorageRoutes(router)
23+
communicationRoutes(router)
2224

2325
updateSwaggerSchemas()
2426

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import KoaRouter from '@koa/router'
2+
import { z } from 'zod'
3+
import { logger, generateRouteMetadata } from '@onecore/utilities'
4+
5+
import * as communicationAdapter from '../../adapters/communication-adapter'
6+
import { registerSchema } from '../../utils/openapi'
7+
8+
const BulkSmsResult = z.object({
9+
successful: z.array(z.string()).describe('Phone numbers that received SMS'),
10+
invalid: z.array(z.string()).describe('Invalid phone numbers'),
11+
totalSent: z.number(),
12+
totalInvalid: z.number(),
13+
})
14+
15+
const BulkEmailResult = z.object({
16+
successful: z
17+
.array(z.string())
18+
.describe('Email addresses that received email'),
19+
invalid: z.array(z.string()).describe('Invalid email addresses'),
20+
totalSent: z.number(),
21+
totalInvalid: z.number(),
22+
})
23+
24+
/**
25+
* @swagger
26+
* openapi: 3.0.0
27+
* tags:
28+
* - name: Communication service
29+
* description: Operations related to communication (SMS, email)
30+
* components:
31+
* securitySchemes:
32+
* bearerAuth:
33+
* type: http
34+
* scheme: bearer
35+
* bearerFormat: JWT
36+
* security:
37+
* - bearerAuth: []
38+
*/
39+
40+
export const routes = (router: KoaRouter) => {
41+
registerSchema('BulkSmsResult', BulkSmsResult)
42+
registerSchema('BulkEmailResult', BulkEmailResult)
43+
44+
/**
45+
* @swagger
46+
* /contacts/send-bulk-sms:
47+
* post:
48+
* summary: Send SMS to multiple contacts
49+
* description: Send SMS messages to multiple phone numbers
50+
* tags:
51+
* - Communication service
52+
* requestBody:
53+
* required: true
54+
* content:
55+
* application/json:
56+
* schema:
57+
* type: object
58+
* required:
59+
* - phoneNumbers
60+
* - text
61+
* properties:
62+
* phoneNumbers:
63+
* type: array
64+
* items:
65+
* type: string
66+
* description: Array of phone numbers
67+
* text:
68+
* type: string
69+
* description: SMS message content
70+
* responses:
71+
* '200':
72+
* description: SMS sent successfully
73+
* content:
74+
* application/json:
75+
* schema:
76+
* type: object
77+
* properties:
78+
* content:
79+
* $ref: '#/components/schemas/BulkSmsResult'
80+
* '400':
81+
* description: Invalid request
82+
* '500':
83+
* description: Internal server error
84+
* security:
85+
* - bearerAuth: []
86+
*/
87+
router.post('(.*)/contacts/send-bulk-sms', async (ctx) => {
88+
const metadata = generateRouteMetadata(ctx)
89+
const result = await communicationAdapter.sendBulkSms(ctx.request.body)
90+
91+
if (result.ok) {
92+
ctx.status = 200
93+
ctx.body = { content: result.data, ...metadata }
94+
} else {
95+
ctx.status = result.statusCode ?? 500
96+
ctx.body = { error: result.err, ...metadata }
97+
}
98+
})
99+
100+
/**
101+
* @swagger
102+
* /contacts/send-bulk-email:
103+
* post:
104+
* summary: Send email to multiple contacts
105+
* description: Send email messages to multiple email addresses
106+
* tags:
107+
* - Communication service
108+
* requestBody:
109+
* required: true
110+
* content:
111+
* application/json:
112+
* schema:
113+
* type: object
114+
* required:
115+
* - emails
116+
* - subject
117+
* - text
118+
* properties:
119+
* emails:
120+
* type: array
121+
* items:
122+
* type: string
123+
* description: Array of email addresses
124+
* subject:
125+
* type: string
126+
* description: Email subject
127+
* text:
128+
* type: string
129+
* description: Email message content
130+
* responses:
131+
* '200':
132+
* description: Email sent successfully
133+
* content:
134+
* application/json:
135+
* schema:
136+
* type: object
137+
* properties:
138+
* content:
139+
* $ref: '#/components/schemas/BulkEmailResult'
140+
* '400':
141+
* description: Invalid request
142+
* '500':
143+
* description: Internal server error
144+
* security:
145+
* - bearerAuth: []
146+
*/
147+
router.post('(.*)/contacts/send-bulk-email', async (ctx) => {
148+
const metadata = generateRouteMetadata(ctx)
149+
const result = await communicationAdapter.sendBulkEmail(ctx.request.body)
150+
151+
if (result.ok) {
152+
ctx.status = 200
153+
ctx.body = { content: result.data, ...metadata }
154+
} else {
155+
ctx.status = result.statusCode ?? 500
156+
ctx.body = { error: result.err, ...metadata }
157+
}
158+
})
159+
}

0 commit comments

Comments
 (0)