route.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import { NextResponse } from 'next/server';
  2. const openApiSpec = {
  3. openapi: '3.0.0',
  4. info: {
  5. title: 'Vtorio API',
  6. version: '1.0.0',
  7. description: 'File upload and management API for Vtorio application',
  8. },
  9. servers: [
  10. {
  11. url: 'http://localhost:3000',
  12. description: 'Development server',
  13. },
  14. ],
  15. components: {
  16. schemas: {
  17. File: {
  18. type: 'object',
  19. properties: {
  20. id: { type: 'string' },
  21. filename: { type: 'string' },
  22. mimetype: { type: 'string' },
  23. size: { type: 'number' },
  24. createdAt: { type: 'string', format: 'date-time' },
  25. updatedAt: { type: 'string', format: 'date-time' },
  26. },
  27. },
  28. },
  29. },
  30. paths: {
  31. '/api/upload': {
  32. post: {
  33. summary: 'Upload a file',
  34. description: 'Upload a file to the server and store it in the database',
  35. tags: ['Files'],
  36. requestBody: {
  37. required: true,
  38. content: {
  39. 'multipart/form-data': {
  40. schema: {
  41. type: 'object',
  42. properties: {
  43. file: {
  44. type: 'string',
  45. format: 'binary',
  46. description: 'The file to upload',
  47. },
  48. },
  49. required: ['file'],
  50. },
  51. },
  52. },
  53. },
  54. responses: {
  55. '200': {
  56. description: 'File uploaded successfully',
  57. content: {
  58. 'application/json': {
  59. schema: {
  60. type: 'object',
  61. properties: {
  62. success: { type: 'boolean', example: true },
  63. file: {
  64. type: 'object',
  65. properties: {
  66. id: { type: 'string', example: 'clh123abc456' },
  67. filename: { type: 'string', example: 'document.pdf' },
  68. mimetype: { type: 'string', example: 'application/pdf' },
  69. size: { type: 'number', example: 1024000 },
  70. createdAt: { type: 'string', format: 'date-time' },
  71. },
  72. },
  73. },
  74. },
  75. },
  76. },
  77. },
  78. '400': {
  79. description: 'Bad request - No file provided',
  80. content: {
  81. 'application/json': {
  82. schema: {
  83. type: 'object',
  84. properties: {
  85. success: { type: 'boolean', example: false },
  86. error: { type: 'string', example: 'No file provided' },
  87. },
  88. },
  89. },
  90. },
  91. },
  92. '500': {
  93. description: 'Internal server error',
  94. content: {
  95. 'application/json': {
  96. schema: {
  97. type: 'object',
  98. properties: {
  99. success: { type: 'boolean', example: false },
  100. error: { type: 'string', example: 'Failed to upload file' },
  101. },
  102. },
  103. },
  104. },
  105. },
  106. },
  107. },
  108. },
  109. '/api/files': {
  110. get: {
  111. summary: 'List all files',
  112. description: 'Get a list of all uploaded files with metadata',
  113. tags: ['Files'],
  114. responses: {
  115. '200': {
  116. description: 'List of files retrieved successfully',
  117. content: {
  118. 'application/json': {
  119. schema: {
  120. type: 'object',
  121. properties: {
  122. success: { type: 'boolean', example: true },
  123. files: {
  124. type: 'array',
  125. items: {
  126. type: 'object',
  127. properties: {
  128. id: { type: 'string', example: 'clh123abc456' },
  129. filename: { type: 'string', example: 'document.pdf' },
  130. mimetype: { type: 'string', example: 'application/pdf' },
  131. size: { type: 'number', example: 1024000 },
  132. createdAt: { type: 'string', format: 'date-time' },
  133. updatedAt: { type: 'string', format: 'date-time' },
  134. },
  135. },
  136. },
  137. },
  138. },
  139. },
  140. },
  141. },
  142. '500': {
  143. description: 'Internal server error',
  144. content: {
  145. 'application/json': {
  146. schema: {
  147. type: 'object',
  148. properties: {
  149. success: { type: 'boolean', example: false },
  150. error: { type: 'string', example: 'Failed to list files' },
  151. },
  152. },
  153. },
  154. },
  155. },
  156. },
  157. },
  158. },
  159. '/api/files/{id}': {
  160. get: {
  161. summary: 'Download a file',
  162. description: 'Download a specific file by its ID',
  163. tags: ['Files'],
  164. parameters: [
  165. {
  166. name: 'id',
  167. in: 'path',
  168. required: true,
  169. description: 'The ID of the file to download',
  170. schema: {
  171. type: 'string',
  172. example: 'clh123abc456',
  173. },
  174. },
  175. ],
  176. responses: {
  177. '200': {
  178. description: 'File downloaded successfully',
  179. content: {
  180. 'application/octet-stream': {
  181. schema: {
  182. type: 'string',
  183. format: 'binary',
  184. },
  185. },
  186. },
  187. headers: {
  188. 'Content-Type': {
  189. description: 'MIME type of the file',
  190. schema: { type: 'string' },
  191. },
  192. 'Content-Disposition': {
  193. description: 'Attachment header with filename',
  194. schema: { type: 'string' },
  195. },
  196. 'Content-Length': {
  197. description: 'Size of the file in bytes',
  198. schema: { type: 'integer' },
  199. },
  200. },
  201. },
  202. '404': {
  203. description: 'File not found',
  204. content: {
  205. 'application/json': {
  206. schema: {
  207. type: 'object',
  208. properties: {
  209. error: { type: 'string', example: 'File not found' },
  210. },
  211. },
  212. },
  213. },
  214. },
  215. '500': {
  216. description: 'Internal server error',
  217. content: {
  218. 'application/json': {
  219. schema: {
  220. type: 'object',
  221. properties: {
  222. error: { type: 'string', example: 'Failed to retrieve file' },
  223. },
  224. },
  225. },
  226. },
  227. },
  228. },
  229. },
  230. },
  231. },
  232. };
  233. export const GET = async () => {
  234. return NextResponse.json(openApiSpec, {
  235. headers: {
  236. 'Content-Type': 'application/json',
  237. },
  238. });
  239. };