49 Commits

Author SHA1 Message Date
Ümit Tunç 69debeeffd feat: add restart script for automated deployment and container lifecycle management 2026-04-27 17:54:02 +03:00
Ümit Tunç 266447e03d fix: improve API error handling, add fallback UI, and optimize Nginx connection settings 2026-04-07 15:59:30 +03:00
Ümit Tunç 747043d616 Update Docker Compose configuration for service port changes
- Changed the web service port mapping from 8088 to 8089 to avoid conflicts.
- Updated the database service port mapping from 3307 to 3308 for better alignment with application requirements.

These changes improve the accessibility and organization of the Docker setup for the Truncgil Finance application.
2025-10-25 17:10:02 -03:00
Ümit Tunç be9d6e3687 Update endpoint responses and configuration for currency, gold, and crypto rates
- Updated response content for endpoints to reflect current rates as of September 15, 2025, including changes in currency and gold prices.
- Modified example values for URL parameters to improve clarity and consistency.
- Changed the theme configuration in the Scribe documentation from 'elements' to 'scalar' for better presentation.
- Refactored the HTML structure in the Scribe index view to streamline the layout and improve accessibility.

These changes collectively enhance the accuracy and usability of the API documentation and responses in the Truncgil Finance application.
2025-09-15 11:14:02 -03:00
Ümit Tunç 15abebe9ed Update Nginx configuration for enhanced security and performance
- Changed file permissions for default.conf to improve security.
- Added security headers (X-Frame-Options, X-XSS-Protection, X-Content-Type-Options) to enhance protection against common vulnerabilities.
- Included additional parameters for PHP processing to support HTTPS and improve handling of requests.
- Implemented restrictions to deny access to hidden files and log files, further securing the application.

These changes collectively strengthen the security posture and performance of the Nginx configuration for the Truncgil Finance application.
2025-09-15 11:06:34 -03:00
Ümit Tunç beaac25180 Update Docker configuration for service port and cleanup
- Changed the web service port mapping from 8081 to 8088 for better alignment with application requirements.
- Removed unnecessary NTP installation and commands from the Dockerfile to streamline the build process.

These changes enhance the Docker setup for the Truncgil Finance application by improving service accessibility and optimizing the build configuration.
2025-09-15 11:06:16 -03:00
Ümit Tunç b494d45ed8 Add currency test data and enhance FetchCurrencyRates job with TCMB integration
- Introduced a new JSON file containing currency rates for various currencies, including USD, EUR, and GBP, to standardize currency data representation.
- Enhanced the FetchCurrencyRates job to fetch USD data from TCMB if not available, improving data reliability.
- Added logging for TCMB data fetching process to assist in monitoring and debugging.

These changes collectively improve the accuracy and robustness of currency rate handling in the Truncgil Finance application.
2025-07-05 09:48:07 +03:00
Ümit Tunç 41eaf7c6df Update gold rate naming convention in FetchGoldRates job
- Changed the abbreviation for "22AYARBILEZIK" from "YIB" to "YIA" to improve clarity and consistency in the naming convention for gold rates.

This change enhances the accuracy of the data representation in the FetchGoldRates job within the Truncgil Finance application.
2025-04-22 10:36:45 +03:00
Ümit Tunç 6ddf932bea Update docker-compose configuration for improved service management
- Added 'restart: always' policy to the app and web services to ensure they restart automatically on failure.
- Changed network names from 'laravel-network' to 'app-network' for better clarity and consistency.
- Updated the network configuration to use a bridge driver for improved networking capabilities.

These changes enhance the reliability and organization of the Docker setup for the Truncgil Finance application.
2025-04-22 10:15:39 +03:00
Ümit Tunç 93c7f74356 Enhance FetchGoldRates job with improved data handling and logging
- Added logging for data-socket-key values to assist in debugging and monitoring.
- Refined the extraction of gold rates to include specific metal types (Gold, Palladium, Platinum, Silver) based on the data attributes.
- Updated the user agent and accept language headers for improved compatibility with the data source.
- Enhanced the naming convention for gold rates to ensure clarity and consistency in the data structure.

These changes collectively improve the functionality and maintainability of the FetchGoldRates job in the Truncgil Finance application.
2025-04-22 10:15:14 +03:00
Ümit Tunç 7fc4683cb3 Add favicon for the application
- Introduced a new favicon.png file to enhance the visual branding of the application
- Placed the favicon in the public/img directory for easy access and deployment
2025-01-25 08:42:48 +03:00
Ümit Tunç 8be72acf26 Enhance welcome page with new resource links and improved UI elements
- Added a new link to the Postman collection for easier access to API documentation.
- Introduced a link to the SwaggerHub collection, providing users with additional API resources.
- Updated existing links to open in a new tab for better user experience.
- Enhanced SVG icons and text descriptions for clarity and visual appeal.

These changes collectively improve the accessibility and usability of API resources on the welcome page of the Truncgil Finance application.
2025-01-22 08:48:35 +03:00
Ümit Tunç fc32aa6935 Refactor API documentation and endpoints for currency, crypto, and gold rates
- Updated endpoint names and descriptions for clarity, including renaming 'Endpoints' to 'Cron Job' and enhancing titles for better understanding.
- Introduced new endpoints for fetching all rates, current currency rates, gold rates, and crypto rates, improving the API's structure and usability.
- Enhanced response messages to provide comprehensive updates for all currency, crypto, and gold rates, ensuring consistency and clarity.
- Improved metadata and organization within the API documentation for better navigation and user experience.

These changes collectively enhance the clarity, usability, and functionality of the API in the Truncgil Finance application.
2025-01-21 22:50:48 +03:00
Ümit Tunç c37373c083 Enhance TimeDateController API documentation
- Updated method descriptions for fetching server time and date to improve clarity.
- Added grouping and subgroup annotations for better organization in API documentation.
- These changes collectively enhance the usability and clarity of the TimeDateController in the Truncgil Finance application.
2025-01-21 22:50:38 +03:00
Ümit Tunç 0ab592ecbc Refactor CurrencyController to enhance API documentation and response messages
- Updated method documentation to clearly describe the fetching of currency, crypto, and gold rates.
- Improved response messages to include all relevant rates (currency, crypto, and gold) for better clarity.
- Added grouping and subgroup annotations to API methods for improved organization in documentation.
- Enhanced consistency in method descriptions across the controller.

These changes collectively improve the clarity and usability of the CurrencyController in the Truncgil Finance application.
2025-01-21 22:50:30 +03:00
Ümit Tunç 41fa599cd3 Update API responses for currency and gold rates with English translations and improved metadata
- Translated API response messages from Turkish to English for consistency and clarity.
- Updated response contents to reflect the latest currency and gold rates, including accurate timestamps and metadata.
- Changed example values for currency and gold names to enhance API documentation clarity.
- Adjusted server time in responses to ensure accurate time representation.

These changes collectively improve the usability and clarity of the currency and gold rates API in the Truncgil Finance application.
2025-01-21 22:30:04 +03:00
Ümit Tunç 7294890f06 Update currency and gold rates API responses with enhanced metadata and example values
- Modified the title of the endpoint to include a Bitcoin symbol for clarity.
- Updated API response contents to reflect the latest currency and gold rates, including timestamps and metadata.
- Changed example values for currency and gold names to improve clarity in API documentation.
- Adjusted server time in responses to ensure accurate time representation.

These changes collectively enhance the usability and accuracy of the currency and gold rates API in the Truncgil Finance application.
2025-01-21 22:29:38 +03:00
Ümit Tunç 0d6e449808 Refactor Console Kernel to include MergeCurrencyAndGoldRates job
- Added the MergeCurrencyAndGoldRates job to the Console Kernel, ensuring it is now part of the job dispatching process.
- This change improves the overall functionality of scheduled tasks related to currency and gold rates, enhancing data integration within the Truncgil Finance application.
2025-01-21 22:29:17 +03:00
Ümit Tunç 9409a4dbd9 Refactor CurrencyController to improve error handling and update messages
- Reordered the dispatching of jobs in the runAllFetchs method to ensure proper execution sequence.
- Updated API response messages from Turkish to English for consistency and clarity.
- Enhanced error messages for data retrieval failures to provide clearer feedback to users.
- Improved documentation comments to reflect the changes in functionality.

These changes collectively enhance the usability and clarity of the CurrencyController in the Truncgil Finance application.
2025-01-21 22:29:08 +03:00
Ümit Tunç a46f286ce2 Add FetchCryptoCurrencyRates job to Console Kernel
- Introduced the FetchCryptoCurrencyRates job in the Console Kernel to facilitate the fetching of cryptocurrency rates.
- This addition enhances the scheduled tasks functionality, allowing for better integration of cryptocurrency data within the application.
2025-01-21 21:47:01 +03:00
Ümit Tunç bf016af07c Refactor RouteServiceProvider to remove custom rate limiting for API requests
- Removed the custom rate limiter for API requests in RouteServiceProvider, simplifying the boot method.
- This change streamlines the routing setup and prepares for potential future enhancements in request handling.
2025-01-21 21:28:39 +03:00
Ümit Tunç 61c7a77431 Add FetchCryptoCurrencyRates job to scheduled tasks and clean up RouteServiceProvider 2025-01-21 21:28:33 +03:00
Ümit Tunç 09e981f94b Implement crypto currency rates feature and enhance API responses
- Added a new job to fetch crypto currency rates from an external source and store them in a JSON file.
- Updated the CurrencyController to include methods for retrieving current crypto currency rates and rates by name.
- Enhanced the API to return detailed metadata for crypto currency rates, including timestamps and update information.
- Updated the API routes to support new endpoints for crypto currency rates.
- Modified the merged rates JSON to include crypto currency data alongside existing currency and gold rates.
- Improved the welcome view to display additional crypto currency information, enhancing user experience.

These changes collectively expand the functionality of the Truncgil Finance application, providing users with comprehensive access to crypto currency data.
2025-01-21 19:27:03 +03:00
Ümit Tunç 30dd0c5b8d Enhance currency and gold rates API with custom throttling and improved responses
- Implemented a custom throttle middleware to limit requests to 2 per 30 seconds, enhancing API stability.
- Updated API responses to include Turkish messages for successful updates and error handling.
- Refactored the CurrencyController to integrate the new throttling logic and improve response clarity.
- Enhanced the Scribe documentation to reflect changes in API behavior and response formats.
- Updated views to improve branding and user experience, including dynamic content adjustments.

These changes collectively improve the API's performance, usability, and branding for the Truncgil Finance application.
2025-01-21 18:28:39 +03:00
Ümit Tunç e2684ef05a Update currency and gold rates API responses, enhance views, and improve branding
- Updated API responses for currency and gold rates to include the latest data and improved metadata, ensuring accurate and informative responses.
- Added a new view for displaying currency rates, enhancing the user interface with dynamic data presentation.
- Updated the welcome view to integrate the new currency display and improved layout for better user experience.
- Changed the logo in the Scribe configuration to a new light SVG for better visual consistency.
- Enhanced styling in the welcome view and currency display for a modern look and feel.

These changes collectively improve the functionality, usability, and branding of the Truncgil Finance application.
2025-01-21 18:05:33 +03:00
Ümit Tunç c478be2f3f - Added a new favicon and manifest file for the Truncgil Finance application to enhance branding and user experience.
- Updated the Scribe configuration to use a new theme and included a logo for better visual identity.
- Enhanced the welcome view by linking to the new manifest and updating the background image source for improved accessibility.
- Refactored API documentation to include updated response formats and example values, ensuring clarity and usability.
- Improved the layout and structure of the Scribe documentation pages for a more responsive design.

These changes collectively enhance the branding, accessibility, and usability of the Truncgil Finance application.
2025-01-21 18:05:24 +03:00
Ümit Tunç 84b9182937 - Added a new light logo SVG file for Truncgil Finance to enhance branding.
- Updated the existing logo SVG file to improve its structure and styling, including changes to the DOCTYPE and color definitions.
- Refactored the logo paths and styles for better performance and visual consistency across the application.
These changes improve the visual identity of the Truncgil Finance application, ensuring a modern and cohesive branding experience.
2025-01-21 15:25:16 +03:00
Ümit Tunç d381fdfbe1 - Added a new SVG logo for Truncgil Finance to the project.
- Updated the title in the welcome view to reflect the new branding.
- Replaced the existing logo in the welcome view with the newly added SVG logo.
- Modified the background image alt text for better accessibility.
- Updated footer information to display the Truncgil Finance version instead of Laravel.
- Enhanced the welcome view layout by removing unnecessary elements and improving the overall structure.

These changes enhance the branding and user experience of the Truncgil Finance application.
2025-01-21 15:04:39 +03:00
Ümit Tunç f860ce5e5c - Enhanced Dockerfile for Laravel application by updating file permissions and improving cron job configuration.
- Added NTP service initialization to ensure accurate time synchronization within the container.
- Modified cron job command to run all fetch tasks, improving scheduled task management.
- Included additional echo statements for better logging during the setup process.
These changes improve the Docker environment's reliability and enhance the functionality of scheduled tasks in the Laravel application.
2025-01-21 11:06:55 +03:00
Ümit Tunç 74d2e3e602 - Updated CurrencyController to enhance API responses for currency and gold rates.
- Added metadata to the responses, including timestamps and the time since the last update, improving data context for users.
- Enhanced method descriptions with relevant emojis for better readability and understanding.
- Refactored response handling to ensure consistent JSON structure across all rate retrieval methods.
- These changes improve the clarity and usability of the API, providing users with more informative responses.
2025-01-21 11:06:42 +03:00
Ümit Tunç 725fb50e03 Update Docker configuration and comment out Laravel migration commands
- Updated the Docker Compose file to specify the latest image tag for the application.
- Commented out the Laravel migration commands in the Dockerfile to prevent automatic migrations during container build, enhancing control over the deployment process.
- These changes improve the Docker setup and provide better management of the Laravel application lifecycle.
2025-01-21 09:35:27 +03:00
Ümit Tunç 3e10131f81 Refactor Docker setup and update API documentation
- Renamed Dockerfile to lowercase for consistency and clarity.
- Introduced a new Dockerfile for the Laravel application, utilizing PHP 8.2 and installing necessary dependencies, including NTP for time synchronization.
- Removed the docker-entrypoint.sh script, which previously generated API documentation, streamlining the container startup process.
- Updated API documentation with new response formats and example values for `currencyName` and `goldName`, enhancing clarity and usability.
- Adjusted endpoint responses to reflect the latest currency and gold rates, ensuring accurate data delivery.

These changes improve the Docker environment and enhance the API's documentation and response accuracy, contributing to a more robust application setup.
2025-01-21 09:28:15 +03:00
Ümit Tunç 677da3892d Update RunAllFetchs command description for clarity
- Changed the command description to provide a clearer understanding of its functionality, specifying that it runs all fetch jobs for currency and gold rates. This enhances documentation and usability for developers interacting with the command.
2025-01-20 23:47:17 +03:00
Ümit Tunç c62211f393 Add new API endpoints for fetching server time and date, and update currency and gold rates responses
- Introduced two new endpoints: `/api/server-time` and `/api/server-date` to retrieve the current server time and date.
- Enhanced the existing currency and gold rates endpoints to return a 200 status with updated response formats, replacing previous 404 error messages.
- Updated example values for `currencyName` and `goldName` in the API documentation for improved clarity.
- Improved overall API functionality and user experience by providing accurate and accessible time-related information.
2025-01-20 22:44:17 +03:00
Ümit Tunç 2ec15193a0 Add server time and date endpoints to API
- Introduced two new API endpoints: `/server-time` and `/server-date` in the `api.php` routes file.
- Integrated `TimeDateController` to handle requests for current server time and date.
- Enhanced API functionality by providing users with easy access to server time and date information.
2025-01-20 22:44:03 +03:00
Ümit Tunç 32119b6911 Add TimeDateController for server time and date API endpoints</message>
<message>
- Introduced TimeDateController with two new endpoints: `/server-time` and `/server-date`.
- Implemented methods to return the current server time and date in JSON format.
- Enhanced API functionality by providing easy access to server time and date information.
2025-01-20 22:43:52 +03:00
Ümit Tunç c7b06c0cba Enhance Dockerfile for Laravel application with NTP support
- Added NTP package installation to synchronize time within the container.
- Configured a cron job for automatic time updates, improving time accuracy for scheduled tasks.
- Updated file permission settings and added echo statements for better logging and clarity during setup.

These changes enhance the Docker environment by ensuring accurate timekeeping, which is crucial for scheduled tasks in the Laravel application.
2025-01-20 22:43:45 +03:00
Ümit Tunç 7d108ca032 Add Dockerfile for Laravel application setup
- Introduced a new Dockerfile utilizing PHP 8.2 for the Laravel application.
- Configured timezone settings and installed necessary dependencies including Git, cURL, and PHP extensions.
- Set up cron jobs for Laravel task scheduling and included Composer for dependency management.
- Implemented file permission settings to enhance security and functionality across application directories.
- Added commands for Laravel application initialization, including migration, key generation, and caching operations.
- Included a custom entrypoint script to streamline container startup processes.

These changes establish a robust Docker environment for the Laravel application, improving deployment and operational efficiency.
2025-01-20 22:16:17 +03:00
Ümit Tunç 5283c8aac9 Update API documentation and configuration files
- Changed the base URL in the introduction documentation from `http://localhost:8000` to `https://finance.truncgil.com` for accurate API access.
- Updated the `.filehashes` to reflect changes in the `intro.md` file.
- Modified API endpoint responses to return a 404 status with a more user-friendly error message: "Data not found" instead of "Currency not found".
- Revised example values for `currencyName` and `goldName` in the API documentation to improve clarity and usability.
- Added a new Nginx configuration file to set up server parameters for the application.
- Adjusted file permissions for various `.gitignore` files to enhance security.

These changes improve the accuracy of the API documentation and enhance the overall user experience when interacting with the API.
2025-01-20 22:12:03 +03:00
Ümit Tunç df5a21efa7 Uncomment run-all-fetchs route in API for currency updates
- Restored the route for the 'run-all-fetchs' method in the CurrencyController, enabling the endpoint for fetching all currency and gold rates.
- This change enhances the API functionality by making the route accessible for clients, improving the overall user experience in managing financial data.
2025-01-20 22:11:51 +03:00
Ümit Tunç 63aa362100 Enhance runAllFetchs method in CurrencyController for error handling and response formatting
- Wrapped job dispatching calls in a try-catch block to handle potential exceptions during the fetching of currency and gold rates.
- Added JSON response for both success and error scenarios, improving the API's feedback mechanism for clients.
- Updated method documentation to reflect the return type of the method.

These changes improve the robustness and user experience of the currency and gold rates update process.
2025-01-20 22:11:35 +03:00
Ümit Tunç 5d6b9a2f48 Add docker-entrypoint.sh for API documentation generation
- Introduced a new script to automate the generation of API documentation using the `php artisan scribe:generate` command.
- This addition streamlines the process of keeping API documentation up-to-date, enhancing developer experience and project maintainability.
2025-01-20 22:11:20 +03:00
Ümit Tunç 700bfb2994 Update composer.lock to correct stability flags and platform-dev settings
- Changed stability-flags from an array to an object for better compatibility with Composer.
- Updated platform-dev from an array to an object to align with the latest Composer standards.

These changes ensure the composer.lock file adheres to the expected format, improving dependency management.
2025-01-20 22:11:10 +03:00
Ümit Tunç c20b900e33 Add .htaccess file for HTTPS redirection
- Introduced a new .htaccess file to enforce HTTPS by redirecting all HTTP requests to their HTTPS counterparts.
- This change enhances security by ensuring that all traffic to the application is encrypted.
2025-01-20 22:10:54 +03:00
Ümit Tunç 5c96b6b72e Update Docker configuration and Dockerfile for Laravel application
- Changed the Docker image for the app service to 'truncgil-finance-app' and updated the container name accordingly.
- Modified the web service to use 'truncgil-finance-web' and changed the port mapping to 8081.
- Upgraded the database image to MySQL 8.0 and updated the container name to 'truncgil-finance-db', adding a restart policy.
- Added environment variables for timezone and application settings in the app service.
- Updated the Dockerfile to use PHP 8.2, added necessary dependencies, and configured cron jobs for Laravel tasks.
- Enhanced file permission settings for the application directory to improve security and functionality.

These changes improve the overall configuration and performance of the Laravel application within the Docker environment.
2025-01-20 22:10:47 +03:00
Ümit Tunç 026ee3f85d Merge branch 'docker-version' of https://github.com/truncgil/truncgil_finance into docker-version 2025-01-20 16:26:44 +03:00
Ümit Tunç dace80dd79 Update currency and gold rates API endpoints with new data
- Updated response content for currency and gold rates to reflect the latest values as of January 20, 2025.
- Revised example values in URL parameters for `currencyName` and `goldName` to provide more realistic usage scenarios.
- Enhanced overall clarity and consistency in API responses, improving usability for developers interacting with financial data.

These changes ensure the API provides accurate and up-to-date information, facilitating better management of financial data.
2025-01-20 16:43:41 +03:00
Ümit Tunç f23743adab Enhance Dockerfile with file permission settings
- Added commands to set ownership and permissions for the /var/www directory and its subdirectories, ensuring proper access for the web server.
- This change improves security and functionality by configuring the environment for the Laravel application.
2025-01-20 16:25:22 +03:00
Ümit Tunç 944758a215 Add Docker configuration and Dockerfile for Laravel application 2025-01-18 18:58:24 +03:00
64 changed files with 1928 additions and 549 deletions
+3
View File
@@ -0,0 +1,3 @@
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
+1 -1
View File
@@ -1,4 +1,4 @@
# GENERATED. YOU SHOULDN'T MODIFY OR DELETE THIS FILE. # GENERATED. YOU SHOULDN'T MODIFY OR DELETE THIS FILE.
# Scribe uses this file to know when you change something manually in your docs. # Scribe uses this file to know when you change something manually in your docs.
.scribe/intro.md=5ba4520f0a0f744a7aceda778b683bb0 .scribe/intro.md=731671c57601ba874fec492fc1cf37ad
.scribe/auth.md=9bee2b1ef8a238b2e58613fa636d5f39 .scribe/auth.md=9bee2b1ef8a238b2e58613fa636d5f39
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+94
View File
@@ -0,0 +1,94 @@
## Autogenerated by Scribe. DO NOT MODIFY.
name: '🪙 Gold'
description: ''
endpoints:
-
httpMethods:
- GET
uri: api/gold-rates
metadata:
groupName: '🪙 Gold'
groupDescription: ''
subgroup: 'Fetch Rates'
subgroupDescription: ''
title: 'Get current gold rates.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters: []
cleanUrlParameters: []
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 200
content: '{"Meta_Data":{"Minutes_Ago":-0.01,"Current_Date":"2025-09-15 17:13:46","Update_Date":"2025-09-15 17:13:46"},"Rates":{"GRA":{"Selling":4858.08,"Type":"Gold","Name":"GRAMALTIN","Change":0.26,"Buying":4857.61},"XU100":{"Selling":10931.75,"Type":"Gold","Name":"XU100","Change":5.4},"DBITCOIN":{"Selling":0,"Type":"Gold","Name":"DBITCOIN","Change":-0.87},"GUMUS":{"Selling":56.07,"Type":"Gold","Name":"GUMUS","Change":-0.12,"Buying":56.03},"BRENT":{"Selling":0,"Type":"Gold","Name":"BRENT","Change":0.99},"ONS":{"Buying":0,"Type":"Gold","Name":"ONS","Selling":0,"Change":0.45},"HAS":{"Buying":4833.32,"Type":"Gold","Name":"GRAMHASALTIN","Selling":4833.79,"Change":0.26},"CEYREKALTIN":{"Buying":7891.66,"Type":"Gold","Name":"CEYREKALTIN","Selling":8071.59,"Change":0.01},"YARIMALTIN":{"Buying":15734,"Type":"Gold","Name":"YARIMALTIN","Selling":16143.19,"Change":0.01},"TAMALTIN":{"Buying":31566.65,"Type":"Gold","Name":"TAMALTIN","Selling":32187.64,"Change":0.01},"CUMHURIYETALTINI":{"Buying":32651,"Type":"Gold","Name":"CUMHURIYETALTINI","Selling":33144,"Change":-0.13},"ATAALTIN":{"Buying":32553.11,"Type":"Gold","Name":"ATAALTIN","Selling":33372.46,"Change":0.01},"14AYARALTIN":{"Buying":2811.4,"Type":"Gold","Name":"14AYARALTIN","Selling":2813.95,"Change":0.01},"18AYARALTIN":{"Buying":3600.57,"Type":"Gold","Name":"18AYARALTIN","Selling":3603.83,"Change":0.01},"YIA":{"Buying":4498.25,"Type":"Gold","Name":"22AYARBILEZIK","Selling":4502.32,"Change":0.01},"IKIBUCUKALTIN":{"Buying":78916.62,"Type":"Gold","Name":"IKIBUCUKALTIN","Selling":80172.88,"Change":0.01},"BESLIALTIN":{"Buying":159806.16,"Type":"Gold","Name":"BESLIALTIN","Selling":162912.88,"Change":0.01},"GREMSEALTIN":{"Buying":78916.62,"Type":"Gold","Name":"GREMSEALTIN","Selling":80715.93,"Change":0.01},"RESATALTIN":{"Buying":32553.11,"Type":"Gold","Name":"RESATALTIN","Selling":33372.46,"Change":0.01},"HAMITALTIN":{"Buying":32553.11,"Type":"Gold","Name":"HAMITALTIN","Selling":33372.46,"Change":0.01},"GPL":{"Buying":1849.92,"Type":"Platinum","Name":"GRAMPLATIN","Selling":1854.44,"Change":-0.58},"PAL":{"Buying":1563.23,"Type":"Palladium","Name":"GRAMPALADYUM","Selling":1567.85,"Change":-1.93}}}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
-
httpMethods:
- GET
uri: 'api/gold-rates/{goldName}'
metadata:
groupName: '🪙 Gold'
groupDescription: ''
subgroup: 'Fetch Rates'
subgroupDescription: ''
title: 'Get gold rate by name.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters:
goldName:
name: goldName
description: ''
required: true
example: rerum
type: string
enumValues: []
exampleWasSpecified: false
nullable: false
custom: []
cleanUrlParameters:
goldName: rerum
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 404
content: '{"error":"Currency not found"}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
File diff suppressed because one or more lines are too long
+83
View File
@@ -0,0 +1,83 @@
## Autogenerated by Scribe. DO NOT MODIFY.
name: Time
description: ''
endpoints:
-
httpMethods:
- GET
uri: api/server-time
metadata:
groupName: Time
groupDescription: ''
subgroup: 'Server Info'
subgroupDescription: ''
title: 'Get current server time.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters: []
cleanUrlParameters: []
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 200
content: '{"server_time":"17:13:46"}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
-
httpMethods:
- GET
uri: api/server-date
metadata:
groupName: Time
groupDescription: ''
subgroup: 'Server Info'
subgroupDescription: ''
title: 'Get current server date.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters: []
cleanUrlParameters: []
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 200
content: '{"server_date":"2025-09-15"}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+92
View File
@@ -0,0 +1,92 @@
name: '🪙 Gold'
description: ''
endpoints:
-
httpMethods:
- GET
uri: api/gold-rates
metadata:
groupName: '🪙 Gold'
groupDescription: ''
subgroup: 'Fetch Rates'
subgroupDescription: ''
title: 'Get current gold rates.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters: []
cleanUrlParameters: []
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 200
content: '{"Meta_Data":{"Minutes_Ago":-0.01,"Current_Date":"2025-09-15 17:13:46","Update_Date":"2025-09-15 17:13:46"},"Rates":{"GRA":{"Selling":4858.08,"Type":"Gold","Name":"GRAMALTIN","Change":0.26,"Buying":4857.61},"XU100":{"Selling":10931.75,"Type":"Gold","Name":"XU100","Change":5.4},"DBITCOIN":{"Selling":0,"Type":"Gold","Name":"DBITCOIN","Change":-0.87},"GUMUS":{"Selling":56.07,"Type":"Gold","Name":"GUMUS","Change":-0.12,"Buying":56.03},"BRENT":{"Selling":0,"Type":"Gold","Name":"BRENT","Change":0.99},"ONS":{"Buying":0,"Type":"Gold","Name":"ONS","Selling":0,"Change":0.45},"HAS":{"Buying":4833.32,"Type":"Gold","Name":"GRAMHASALTIN","Selling":4833.79,"Change":0.26},"CEYREKALTIN":{"Buying":7891.66,"Type":"Gold","Name":"CEYREKALTIN","Selling":8071.59,"Change":0.01},"YARIMALTIN":{"Buying":15734,"Type":"Gold","Name":"YARIMALTIN","Selling":16143.19,"Change":0.01},"TAMALTIN":{"Buying":31566.65,"Type":"Gold","Name":"TAMALTIN","Selling":32187.64,"Change":0.01},"CUMHURIYETALTINI":{"Buying":32651,"Type":"Gold","Name":"CUMHURIYETALTINI","Selling":33144,"Change":-0.13},"ATAALTIN":{"Buying":32553.11,"Type":"Gold","Name":"ATAALTIN","Selling":33372.46,"Change":0.01},"14AYARALTIN":{"Buying":2811.4,"Type":"Gold","Name":"14AYARALTIN","Selling":2813.95,"Change":0.01},"18AYARALTIN":{"Buying":3600.57,"Type":"Gold","Name":"18AYARALTIN","Selling":3603.83,"Change":0.01},"YIA":{"Buying":4498.25,"Type":"Gold","Name":"22AYARBILEZIK","Selling":4502.32,"Change":0.01},"IKIBUCUKALTIN":{"Buying":78916.62,"Type":"Gold","Name":"IKIBUCUKALTIN","Selling":80172.88,"Change":0.01},"BESLIALTIN":{"Buying":159806.16,"Type":"Gold","Name":"BESLIALTIN","Selling":162912.88,"Change":0.01},"GREMSEALTIN":{"Buying":78916.62,"Type":"Gold","Name":"GREMSEALTIN","Selling":80715.93,"Change":0.01},"RESATALTIN":{"Buying":32553.11,"Type":"Gold","Name":"RESATALTIN","Selling":33372.46,"Change":0.01},"HAMITALTIN":{"Buying":32553.11,"Type":"Gold","Name":"HAMITALTIN","Selling":33372.46,"Change":0.01},"GPL":{"Buying":1849.92,"Type":"Platinum","Name":"GRAMPLATIN","Selling":1854.44,"Change":-0.58},"PAL":{"Buying":1563.23,"Type":"Palladium","Name":"GRAMPALADYUM","Selling":1567.85,"Change":-1.93}}}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
-
httpMethods:
- GET
uri: 'api/gold-rates/{goldName}'
metadata:
groupName: '🪙 Gold'
groupDescription: ''
subgroup: 'Fetch Rates'
subgroupDescription: ''
title: 'Get gold rate by name.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters:
goldName:
name: goldName
description: ''
required: true
example: rerum
type: string
enumValues: []
exampleWasSpecified: false
nullable: false
custom: []
cleanUrlParameters:
goldName: rerum
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 404
content: '{"error":"Currency not found"}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
File diff suppressed because one or more lines are too long
+81
View File
@@ -0,0 +1,81 @@
name: Time
description: ''
endpoints:
-
httpMethods:
- GET
uri: api/server-time
metadata:
groupName: Time
groupDescription: ''
subgroup: 'Server Info'
subgroupDescription: ''
title: 'Get current server time.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters: []
cleanUrlParameters: []
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 200
content: '{"server_time":"17:13:46"}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
-
httpMethods:
- GET
uri: api/server-date
metadata:
groupName: Time
groupDescription: ''
subgroup: 'Server Info'
subgroupDescription: ''
title: 'Get current server date.'
description: ''
authenticated: false
custom: []
headers:
Content-Type: application/json
Accept: application/json
urlParameters: []
cleanUrlParameters: []
queryParameters: []
cleanQueryParameters: []
bodyParameters: []
cleanBodyParameters: []
fileParameters: []
responses:
-
status: 200
content: '{"server_date":"2025-09-15"}'
headers:
cache-control: 'no-cache, private'
content-type: application/json
access-control-allow-origin: '*'
description: null
custom: []
responseFields: []
auth: []
controller: null
method: null
route: null
custom: []
+1 -1
View File
@@ -3,7 +3,7 @@
Daily Financial Data: Provides access to real-time financial data updated through the Truncgil API, allowing users to track the daily performance of currency exchange rates and cryptocurrencies. Daily Financial Data: Provides access to real-time financial data updated through the Truncgil API, allowing users to track the daily performance of currency exchange rates and cryptocurrencies.
<aside> <aside>
<strong>Base URL</strong>: <code>http://localhost:8000</code> <strong>Base URL</strong>: <code>https://finance.truncgil.com</code>
</aside> </aside>
This documentation aims to provide all the information you need to work with our API. This documentation aims to provide all the information you need to work with our API.
+7 -1
View File
@@ -6,6 +6,7 @@ use Illuminate\Console\Command;
use App\Jobs\FetchCurrencyRates; use App\Jobs\FetchCurrencyRates;
use App\Jobs\FetchGoldRates; use App\Jobs\FetchGoldRates;
use App\Jobs\MergeCurrencyAndGoldRates; use App\Jobs\MergeCurrencyAndGoldRates;
use App\Jobs\FetchCryptoCurrencyRates;
class RunAllFetchs extends Command class RunAllFetchs extends Command
{ {
@@ -21,7 +22,7 @@ class RunAllFetchs extends Command
* *
* @var string * @var string
*/ */
protected $description = 'Command description'; protected $description = 'This command runs all fetch jobs for currency and gold rates.';
/** /**
* Execute the console command. * Execute the console command.
@@ -37,6 +38,11 @@ class RunAllFetchs extends Command
$duration = microtime(true) - $start; $duration = microtime(true) - $start;
$results[] = ['FetchCurrencyRates', number_format($duration, 2)]; $results[] = ['FetchCurrencyRates', number_format($duration, 2)];
$start = microtime(true);
FetchCryptoCurrencyRates::dispatchSync();
$duration = microtime(true) - $start;
$results[] = ['FetchCryptoCurrencyRates', number_format($duration, 2)];
$start = microtime(true); $start = microtime(true);
FetchGoldRates::dispatchSync(); FetchGoldRates::dispatchSync();
$duration = microtime(true) - $start; $duration = microtime(true) - $start;
+4
View File
@@ -6,6 +6,7 @@ use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Jobs\FetchCurrencyRates; use App\Jobs\FetchCurrencyRates;
use App\Jobs\FetchGoldRates; use App\Jobs\FetchGoldRates;
use App\Jobs\FetchCryptoCurrencyRates;
use App\Jobs\MergeCurrencyAndGoldRates; use App\Jobs\MergeCurrencyAndGoldRates;
class Kernel extends ConsoleKernel class Kernel extends ConsoleKernel
@@ -22,6 +23,7 @@ class Kernel extends ConsoleKernel
{ {
$schedule->job(new FetchCurrencyRates())->everyMinute(); $schedule->job(new FetchCurrencyRates())->everyMinute();
$schedule->job(new FetchGoldRates())->everyMinute(); $schedule->job(new FetchGoldRates())->everyMinute();
$schedule->job(new FetchCryptoCurrencyRates())->everyMinute();
$schedule->job(new MergeCurrencyAndGoldRates())->everyMinute(); $schedule->job(new MergeCurrencyAndGoldRates())->everyMinute();
} }
@@ -42,6 +44,8 @@ class Kernel extends ConsoleKernel
$schedule = app(Schedule::class); $schedule = app(Schedule::class);
$schedule->job(new FetchCurrencyRates())->everyMinute(); $schedule->job(new FetchCurrencyRates())->everyMinute();
$schedule->job(new FetchGoldRates())->everyMinute(); $schedule->job(new FetchGoldRates())->everyMinute();
$schedule->job(new FetchCryptoCurrencyRates())->everyMinute();
$schedule->job(new MergeCurrencyAndGoldRates())->everyMinute(); $schedule->job(new MergeCurrencyAndGoldRates())->everyMinute();
// Diğer job'larınızı buraya ekleyin // Diğer job'larınızı buraya ekleyin
+160 -23
View File
@@ -4,8 +4,11 @@ namespace App\Http\Controllers;
use App\Jobs\FetchCurrencyRates; use App\Jobs\FetchCurrencyRates;
use App\Jobs\FetchGoldRates; use App\Jobs\FetchGoldRates;
use App\Jobs\FetchCryptoCurrencyRates;
use App\Jobs\MergeCurrencyAndGoldRates; use App\Jobs\MergeCurrencyAndGoldRates;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\Controller;
/** /**
* Class CurrencyController * Class CurrencyController
@@ -14,37 +17,76 @@ use Illuminate\Support\Facades\Storage;
*/ */
class CurrencyController extends Controller class CurrencyController extends Controller
{ {
/** /**
* Dispatches all jobs to fetch currency and gold rates synchronously. * Synchronously fetch all currency, crypto and gold rates.
* Rate limited to 2 requests per 30 seconds.
* @group Cron Job
*
* @return \Illuminate\Http\JsonResponse
*/ */
public function runAllFetchs() public function runAllFetchs()
{ {
FetchCurrencyRates::dispatchSync(); try {
FetchGoldRates::dispatchSync();
MergeCurrencyAndGoldRates::dispatchSync(); FetchCurrencyRates::dispatchSync();
FetchGoldRates::dispatchSync();
FetchCryptoCurrencyRates::dispatchSync();
MergeCurrencyAndGoldRates::dispatchSync();
return response()->json([
'status' => 'success',
'message' => 'All currency, crypto and gold rates have been successfully updated'
]);
} catch (\Exception $e) {
return response()->json([
'status' => 'error',
'message' => 'Kurlar güncellenirken bir hata oluştu: ' . $e->getMessage()
], 429);
}
} }
/** /**
* Retrieves all gold and currency rates * Get all currency, crypto and gold rates.
* @group All Rates
* @subgroup Fetch Rates
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
public function getAllRates() public function getAllRates()
{ {
// JSON dosyasından oku
$jsonFile = 'merged/rates.json'; $jsonFile = 'merged/rates.json';
if (Storage::exists($jsonFile)) { if (Storage::exists($jsonFile)) {
return response()->json( $data = json_decode(Storage::get($jsonFile), true);
json_decode(Storage::get($jsonFile), true) $currentDate = now();
); $updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
if ($updateDate) {
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2);
$metaData = [
'Minutes_Ago' => $minutesAgo,
'Current_Date' => $currentDate->toDateTimeString(),
'Update_Date' => $updateDate->toDateTimeString(),
];
unset($data['Update_Date']);
$data = [
'Meta_Data' => $metaData,
'Rates' => $data
];
return response()->json($data);
}
} }
return response()->json(['error' => 'Veri bulunamadı'], 404); return response()->json(['error' => 'Data not found'], 404);
} }
/** /**
* Retrieves the current currency rates * Get current currency rates.
* @group 💵 Currency
* @subgroup Fetch Rates
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
@@ -53,16 +95,34 @@ class CurrencyController extends Controller
// JSON dosyasından oku // JSON dosyasından oku
$jsonFile = 'currency/today.json'; $jsonFile = 'currency/today.json';
if (Storage::exists($jsonFile)) { if (Storage::exists($jsonFile)) {
return response()->json( $data = json_decode(Storage::get($jsonFile), true);
json_decode(Storage::get($jsonFile), true) $currentDate = now(); // Şu anki tarih
); $updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
if ($updateDate) {
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2); // Kaç dakika önce alındığı
$metaData = [ // Tarih bilgileri için alt dizi
'Minutes_Ago' => $minutesAgo,
'Current_Date' => $currentDate->toDateTimeString(),
'Update_Date' => $updateDate->toDateTimeString(), // Update_Date burada kalacak
];
unset($data['Update_Date']); // Rates içerisindeki Update_Date elemanını kaldır
$data = [
'Meta_Data' => $metaData, // Tarih bilgileri alt dizisi
'Rates' => $data, // Kur bilgileri alt dizisi
];
}
return response()->json($data);
} }
return response()->json(['error' => 'Veri bulunamadı'], 404); return response()->json(['error' => 'Data not found'], 404);
} }
/** /**
* Retrieves the current gold rates * Get current gold rates.
* @group 🪙 Gold
* @subgroup Fetch Rates
* *
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
@@ -71,16 +131,69 @@ class CurrencyController extends Controller
// JSON dosyasından oku // JSON dosyasından oku
$jsonFile = 'gold/today.json'; $jsonFile = 'gold/today.json';
if (Storage::exists($jsonFile)) { if (Storage::exists($jsonFile)) {
return response()->json( $data = json_decode(Storage::get($jsonFile), true);
json_decode(Storage::get($jsonFile), true) $currentDate = now(); // Şu anki tarih
); $updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
if ($updateDate) {
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2); // Kaç dakika önce alındığı
$metaData = [ // Tarih bilgileri için alt dizi
'Minutes_Ago' => $minutesAgo,
'Current_Date' => $currentDate->toDateTimeString(),
'Update_Date' => $updateDate->toDateTimeString(), // Update_Date burada kalacak
];
unset($data['Update_Date']); // Rates içerisindeki Update_Date elemanını kaldır
$data = [
'Meta_Data' => $metaData, // Tarih bilgileri alt dizisi
'Rates' => $data, // Kur bilgileri alt dizisi
];
}
return response()->json($data);
} }
return response()->json(['error' => 'Veri bulunamadı'], 404); return response()->json(['error' => 'Data not found'], 404);
} }
/** /**
* Retrieves the currency rate by its name * Get current crypto rates.
* @group Crypto
* @subgroup Fetch Rates
*
* @return \Illuminate\Http\JsonResponse
*/
public function getCryptoCurrencyRates()
{
$jsonFile = 'crypto/today.json';
if (Storage::exists($jsonFile)) {
$data = json_decode(Storage::get($jsonFile), true);
$currentDate = now();
$updateDate = isset($data['Update_Date']) ? \Carbon\Carbon::parse($data['Update_Date']) : null;
if ($updateDate) {
$minutesAgo = round($currentDate->diffInMinutes($updateDate), 2);
$metaData = [
'Minutes_Ago' => $minutesAgo,
'Current_Date' => $currentDate->toDateTimeString(),
'Update_Date' => $updateDate->toDateTimeString(),
];
unset($data['Update_Date']);
$data = [
'Meta_Data' => $metaData,
'Rates' => $data,
];
}
return response()->json($data);
}
return response()->json(['error' => 'Data not found'], 404);
}
/**
* Get currency rate by name.
* @group 💵 Currency
* @subgroup Fetch Rates
* *
* @param string $currencyName * @param string $currencyName
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
@@ -101,7 +214,9 @@ class CurrencyController extends Controller
} }
/** /**
* Retrieves the gold rate by its name * Get gold rate by name.
* @group 🪙 Gold
* @subgroup Fetch Rates
* *
* @param string $goldName * @param string $goldName
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
@@ -120,4 +235,26 @@ class CurrencyController extends Controller
return response()->json(['error' => 'Data not found'], 404); return response()->json(['error' => 'Data not found'], 404);
} }
/**
* Get crypto rate by name.
* @group Crypto
* @subgroup Fetch Rates
*
* @param string $cryptoCurrencyName
* @return \Illuminate\Http\JsonResponse
*/
public function getCryptoCurrencyRateByName($cryptoCurrencyName)
{
$jsonFile = 'crypto/today.json';
if (Storage::exists($jsonFile)) {
$data = json_decode(Storage::get($jsonFile), true);
if (isset($data[$cryptoCurrencyName])) {
return response()->json([$cryptoCurrencyName => $data[$cryptoCurrencyName]]);
}
return response()->json(['error' => 'Cryptocurrency not found'], 404);
}
return response()->json(['error' => 'Data not found'], 404);
}
} }
@@ -0,0 +1,60 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
/**
* @OA\Info(title="Time and Date API", version="1.0.0")
*/
class TimeDateController extends Controller
{
/**
* Get current server time.
* @group Time
* @subgroup Server Info
*
* @OA\Get(
* path="/server-time",
* summary="Get Server Time",
* @OA\Response(
* response=200,
* description="Successful response",
* @OA\JsonContent(
* @OA\Property(property="server_time", type="string", example="14:30:00")
* )
* )
* )
*
* @return JsonResponse
*/
public function getServerTime(): JsonResponse
{
return response()->json(['server_time' => date('H:i:s')]);
}
/**
* Get current server date.
* @group Time
* @subgroup Server Info
*
* @OA\Get(
* path="/server-date",
* summary="Get Server Date",
* @OA\Response(
* response=200,
* description="Successful response",
* @OA\JsonContent(
* @OA\Property(property="server_date", type="string", example="2023-10-01")
* )
* )
* )
*
* @return JsonResponse
*/
public function getServerDate(): JsonResponse
{
return response()->json(['server_date' => date('Y-m-d')]);
}
}
+1
View File
@@ -36,6 +36,7 @@ class Kernel extends HttpKernel
'password.confirm' => \Illuminate\Auth\Middleware\EnsurePasswordIsConfirmed::class, 'password.confirm' => \Illuminate\Auth\Middleware\EnsurePasswordIsConfirmed::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'api' => \App\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'api' => \App\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'custom.throttle' => \App\Http\Middleware\CustomThrottleRequests::class,
]; ];
/** /**
@@ -0,0 +1,35 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Cache\RateLimiter;
use Symfony\Component\HttpFoundation\Response;
class CustomThrottleRequests
{
protected $limiter;
public function __construct(RateLimiter $limiter)
{
$this->limiter = $limiter;
}
public function handle(Request $request, Closure $next, $maxAttempts = 60, $decayMinutes = 1): Response
{
$key = $request->ip();
if ($this->limiter->tooManyAttempts($key, $maxAttempts)) {
return response()->json([
'error' => 'Rate limit aşıldı',
'message' => 'Bu endpoint 30 dakikada bir kez çağrılabilir.',
'retry_after' => $this->limiter->availableIn($key)
], 429);
}
$this->limiter->hit($key, $decayMinutes * 60);
return $next($request);
}
}
+82
View File
@@ -0,0 +1,82 @@
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use App\Helpers\NumberFormatter;
class FetchCryptoCurrencyRates implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle()
{
$data = [];
$data['Update_Date'] = now()->format('Y-m-d H:i:s');
// Kripto para kurları
$response = $this->fetchData('https://www.doviz.com/kripto-paralar');
// DOM işlemleri için veri çekme
$dom = new \DOMDocument();
@$dom->loadHTML($response->body());
$xpath = new \DOMXPath($dom);
// Kripto para verilerini içeren tabloyu ID'ye göre bul
$rows = $xpath->query("//table[@id='coins']/tbody/tr");
foreach ($rows as $row) {
$symbol = trim($xpath->evaluate("string(.//td[1]//text()[last()])", $row));
// Semboldeki boşlukları temizle ve sadece kripto para sembolünü al
$symbol = preg_replace('/^.*\s(\w+)\s*$/', '$1', $symbol);
// Kripto para ismini al
$name = $xpath->evaluate("string(.//td[1]//div[@class='cname'])", $row);
if (strlen($symbol) > 0) {
$priceUSD = $xpath->evaluate("string(.//td[2])", $row);
$priceTRY = $xpath->evaluate("string(.//td[3])", $row);
$change = $xpath->evaluate("string(.//td[6])", $row);
// Fiyat verilerini temizle (örn: $3.310,57 -> 3310.57)
$priceUSD = str_replace('$', '', $priceUSD);
$priceUSD = str_replace('.', '', $priceUSD);
$priceUSD = str_replace(',', '.', $priceUSD);
$priceTRY = str_replace('₺', '', $priceTRY);
$priceTRY = str_replace('.', '', $priceTRY);
$priceTRY = str_replace(',', '.', $priceTRY);
$change = str_replace('%', '', $change);
$change = str_replace('.', '', $change);
$change = str_replace(',', '.', $change);
$data[$symbol] = [
'Name' => trim($name),
'USD_Price' => (float)$priceUSD,
'TRY_Price' => (float)$priceTRY,
'Selling' => (float)$priceTRY,
'Change' => (float)$change,
'Type' => 'CryptoCurrency'
];
}
}
// JSON dosyasını kaydet
Storage::put('crypto/today.json', json_encode($data, JSON_UNESCAPED_UNICODE));
return $data;
}
private function fetchData($url)
{
return Http::withHeaders([
'User-Agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10',
'Accept-Language' => 'en'
])->get($url);
}
}
+101 -1
View File
@@ -20,7 +20,7 @@ class FetchCurrencyRates implements ShouldQueue
$data = []; $data = [];
$data['Update_Date'] = now()->format('Y-m-d H:i:s'); $data['Update_Date'] = now()->format('Y-m-d H:i:s');
// Döviz kurları // Döviz kurları - ana kaynak
$response = $this->fetchData('https://kur.doviz.com'); $response = $this->fetchData('https://kur.doviz.com');
// DOM işlemleri için veri çekme // DOM işlemleri için veri çekme
@@ -38,19 +38,39 @@ class FetchCurrencyRates implements ShouldQueue
if (trim($name) !== '') { if (trim($name) !== '') {
if ($name == "JPY") $value = $value / 100; if ($name == "JPY") $value = $value / 100;
if (strlen($name) === 3) { if (strlen($name) === 3) {
// Para birimi ismini bul
$nameElement = $xpath->query(".//div[@class='cname']", $element->parentNode);
if ($nameElement->length > 0) {
$data[$name]['Name'] = trim($nameElement->item(0)->nodeValue);
}
if ($type == "bid") $data[$name]['Buying'] = (float)$value; if ($type == "bid") $data[$name]['Buying'] = (float)$value;
if ($type == "ask") $data[$name]['Selling'] = (float)$value; if ($type == "ask") $data[$name]['Selling'] = (float)$value;
if ($type == "c") $data[$name]['Change'] = round((float)$value, 2); if ($type == "c") $data[$name]['Change'] = round((float)$value, 2);
$data[$name]['Type'] = "Currency"; $data[$name]['Type'] = "Currency";
} }
} }
} }
// Eğer USD verisi yoksa veya boşsa, TCMB'den veri çek
if (!isset($data['USD']) || empty($data['USD']['Buying'])) {
\Log::info('USD verisi bulunamadı, TCMB\'den veri çekiliyor...');
$tcmbData = $this->fetchFromTCMB();
if (!empty($tcmbData)) {
\Log::info('TCMB\'den ' . count($tcmbData) . ' kur alındı');
$data = array_merge($data, $tcmbData);
} else {
\Log::error('TCMB\'den veri alınamadı');
}
}
// AZN kuru için // AZN kuru için
$aznResponse = $this->fetchData('https://wise.com/tr/currency-converter/azn-to-try-rate?amount=1'); $aznResponse = $this->fetchData('https://wise.com/tr/currency-converter/azn-to-try-rate?amount=1');
preg_match('/(\d+\.\d+)\s+TRY/', $aznResponse->body(), $matches); preg_match('/(\d+\.\d+)\s+TRY/', $aznResponse->body(), $matches);
if (isset($matches[1])) { if (isset($matches[1])) {
$data['AZN'] = [ $data['AZN'] = [
'Name' => 'AZERBAYCAN YENİ MANATI',
'Buying' => NumberFormatter::commaToDot($matches[1]), 'Buying' => NumberFormatter::commaToDot($matches[1]),
'Selling' => NumberFormatter::commaToDot($matches[1]), 'Selling' => NumberFormatter::commaToDot($matches[1]),
'Change' => "0.00", 'Change' => "0.00",
@@ -71,4 +91,84 @@ class FetchCurrencyRates implements ShouldQueue
'Accept-Language' => 'en' 'Accept-Language' => 'en'
])->get($url); ])->get($url);
} }
private function fetchFromTCMB()
{
try {
$response = $this->fetchData('https://www.tcmb.gov.tr/kurlar/today.xml');
if (!$response->successful()) {
return [];
}
$xml = simplexml_load_string($response->body());
if (!$xml) {
return [];
}
$data = [];
// Currency mapping - TCMB'deki isimleri kod olarak kullan
$currencyMap = [
'USD' => 'US DOLLAR',
'EUR' => 'EURO',
'GBP' => 'POUND STERLING',
'CHF' => 'SWISS FRANK',
'JPY' => 'JAPENESE YEN',
'CAD' => 'CANADIAN DOLLAR',
'AUD' => 'AUSTRALIAN DOLLAR',
'SEK' => 'SWEDISH KRONA',
'NOK' => 'NORWEGIAN KRONE',
'DKK' => 'DANISH KRONE',
'RUB' => 'RUSSIAN ROUBLE',
'CNY' => 'CHINESE RENMINBI',
'SAR' => 'SAUDI RIYAL',
'KWD' => 'KUWAITI DINAR',
'QAR' => 'QATARI RIAL',
'AED' => 'UNITED ARAB EMIRATES DIRHAM',
'PKR' => 'PAKISTANI RUPEE',
'KRW' => 'SOUTH KOREAN WON',
'AZN' => 'AZERBAIJANI NEW MANAT',
'BGN' => 'BULGARIAN LEV',
'RON' => 'NEW LEU'
];
foreach ($xml->Currency as $currency) {
$code = (string)$currency['CurrencyCode'];
$unit = (float)$currency->Unit;
$name = (string)$currency->CurrencyName;
$buying = (float)$currency->BanknoteBuying;
$selling = (float)$currency->BanknoteSelling;
$forexBuying = (float)$currency->ForexBuying;
$forexSelling = (float)$currency->ForexSelling;
// Birim düzeltmesi (100 yen = 1 birim gibi)
if ($unit > 1) {
$buying = $buying / $unit;
$selling = $selling / $unit;
$forexBuying = $forexBuying / $unit;
$forexSelling = $forexSelling / $unit;
}
// Forex kurları varsa onları kullan, yoksa banknot kurlarını kullan
$finalBuying = $forexBuying > 0 ? $forexBuying : $buying;
$finalSelling = $forexSelling > 0 ? $forexSelling : $selling;
if ($finalBuying > 0 && $finalSelling > 0) {
$data[$code] = [
'Name' => $name,
'Buying' => round($finalBuying, 4),
'Selling' => round($finalSelling, 4),
'Change' => 0.00,
'Type' => 'Currency'
];
}
}
return $data;
} catch (\Exception $e) {
return [];
}
}
} }
+44 -11
View File
@@ -10,6 +10,7 @@ use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Storage;
use App\Helpers\NumberFormatter; use App\Helpers\NumberFormatter;
use Illuminate\Support\Facades\Log;
class FetchGoldRates implements ShouldQueue class FetchGoldRates implements ShouldQueue
{ {
@@ -23,30 +24,59 @@ class FetchGoldRates implements ShouldQueue
// Altın kurları // Altın kurları
$goldResponse = $this->fetchData('https://altin.doviz.com'); $goldResponse = $this->fetchData('https://altin.doviz.com');
$domGold = new \DOMDocument(); $domGold = new \DOMDocument();
@$domGold->loadHTML($goldResponse->body()); @$domGold->loadHTML($goldResponse->body());
$xpathGold = new \DOMXPath($domGold); $xpathGold = new \DOMXPath($domGold);
// Daha spesifik bir sorgu ile sadece ihtiyacımız olan elementleri seçiyoruz
$elementsGold = $xpathGold->query("//*[@data-socket-key]"); $elementsGold = $xpathGold->query("//*[@data-socket-key]");
// Debug için gelen data-socket-key değerlerini loglamak için
$socketKeys = [];
foreach ($elementsGold as $element) { foreach ($elementsGold as $element) {
$attrGold = $element->getAttribute('data-socket-key'); $attrGold = $element->getAttribute('data-socket-key');
$typeGold = $element->getAttribute('data-socket-attr'); $typeGold = $element->getAttribute('data-socket-attr');
$valueGold = NumberFormatter::commaToDot($element->nodeValue); $valueGold = NumberFormatter::commaToDot($element->nodeValue);
if (trim($attrGold) !== '') { // Debug için data-socket-key değerlerini topluyoruz
if (!in_array($attrGold, $socketKeys)) {
$socketKeys[] = $attrGold;
}
if (trim($attrGold) !== '') {
// Önce orijinal ismi tam olarak koruyalım
$nameGold = strtoupper(str_replace("-", "", $attrGold)); $nameGold = strtoupper(str_replace("-", "", $attrGold));
$fullNameGold = $nameGold; $fullNameGold = $nameGold;
$nameGold = str_replace("14", "OD", $nameGold);
$nameGold = str_replace("18", "OS", $nameGold); // Veri tipi belirlemeleri
$nameGold = str_replace("22", "YI", $nameGold); $metalType = "Gold"; // Varsayılan olarak altın
// Özel metaller için tür kontrolü
if (strpos($nameGold, 'GRAMPALADYUM') !== false) {
$metalType = "Palladium";
} elseif (strpos($nameGold, 'GRAMPLATIN') !== false) {
$metalType = "Platinum";
} elseif (strpos($nameGold, 'GRAMGUMUS') !== false) {
$metalType = "Silver";
}
// Kısaltma işlemleri
$nameGold = str_replace("14AYARBILEZIK", "ODB", $nameGold);
$nameGold = str_replace("18AYARBILEZIK", "OSB", $nameGold);
$nameGold = str_replace("22AYARBILEZIK", "YIA", $nameGold);
$nameGold = str_replace("GRAMALTIN", "GRA", $nameGold); $nameGold = str_replace("GRAMALTIN", "GRA", $nameGold);
$nameGold = str_replace("GRAMPLATIN", "GPL", $nameGold); $nameGold = str_replace("GRAMPLATIN", "GPL", $nameGold);
$nameGold = str_replace("GRAMHASALTIN", "HAS", $nameGold); $nameGold = str_replace("GRAMHASALTIN", "HAS", $nameGold);
$nameGold = strtoupper(substr($nameGold, 0, 3)); $nameGold = str_replace("GRAMPALADYUM", "PAL", $nameGold);
$nameGold = str_replace("GRAMGUMUS", "GUM", $nameGold);
// Eğer bir kısaltma yapıldıysa, ilk 3 karakteri al
// Aksi takdirde orijinal değeri kullan
if ($nameGold != $fullNameGold) {
$nameGold = strtoupper(substr($nameGold, 0, 3));
}
$except = ['USD', 'EUR', 'GBP', 'XU1', 'BIT']; $except = ['USD', 'EUR', 'GBP', 'XU1', 'BIT'];
if (in_array($nameGold, $except)) { if (in_array($nameGold, $except)) {
@@ -56,13 +86,15 @@ class FetchGoldRates implements ShouldQueue
if ($typeGold == "bid") $data[$nameGold]['Buying'] = (float)$valueGold; if ($typeGold == "bid") $data[$nameGold]['Buying'] = (float)$valueGold;
if ($typeGold == "ask") $data[$nameGold]['Selling'] = (float)$valueGold; if ($typeGold == "ask") $data[$nameGold]['Selling'] = (float)$valueGold;
if ($typeGold == "s") $data[$nameGold]['Selling'] = (float)$valueGold; if ($typeGold == "s") $data[$nameGold]['Selling'] = (float)$valueGold;
if ($typeGold == "c") $data[$nameGold]['Change'] = round((float)$valueGold, if ($typeGold == "c") $data[$nameGold]['Change'] = round((float)$valueGold, 2);
2); $data[$nameGold]['Type'] = $metalType;
$data[$nameGold]['Type'] = "Gold";
$data[$nameGold]['Name'] = $fullNameGold; $data[$nameGold]['Name'] = $fullNameGold;
} }
} }
// Debug için socket key'leri loglayalım
Log::info('Available data-socket-keys: ' . implode(', ', $socketKeys));
// JSON dosyasını kaydet // JSON dosyasını kaydet
Storage::put('gold/today.json', json_encode($data, JSON_UNESCAPED_UNICODE)); Storage::put('gold/today.json', json_encode($data, JSON_UNESCAPED_UNICODE));
@@ -72,8 +104,9 @@ class FetchGoldRates implements ShouldQueue
private function fetchData($url) private function fetchData($url)
{ {
return Http::withHeaders([ return Http::withHeaders([
'User-Agent' => 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10', 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept-Language' => 'en' 'Accept-Language' => 'tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
])->get($url); ])->get($url);
} }
} }
+2 -1
View File
@@ -17,9 +17,10 @@ class MergeCurrencyAndGoldRates implements ShouldQueue
{ {
$currencyData = $this->getData('currency/today.json'); $currencyData = $this->getData('currency/today.json');
$goldData = $this->getData('gold/today.json'); $goldData = $this->getData('gold/today.json');
$cryptoCurrencyData = $this->getData('crypto/today.json');
// Verileri birleştir // Verileri birleştir
$mergedData = array_merge($currencyData, $goldData); $mergedData = array_merge($currencyData, $goldData, $cryptoCurrencyData);
// Birleştirilmiş veriyi dışarıya aktar // Birleştirilmiş veriyi dışarıya aktar
Storage::put('merged/rates.json', json_encode($mergedData, JSON_UNESCAPED_UNICODE)); Storage::put('merged/rates.json', json_encode($mergedData, JSON_UNESCAPED_UNICODE));
-3
View File
@@ -24,9 +24,6 @@ class RouteServiceProvider extends ServiceProvider
*/ */
public function boot(): void public function boot(): void
{ {
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
$this->routes(function () { $this->routes(function () {
Route::middleware('api') Route::middleware('api')
Regular → Executable
View File
Generated
+2 -2
View File
@@ -8519,12 +8519,12 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": {},
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^8.2" "php": "^8.2"
}, },
"platform-dev": [], "platform-dev": {},
"plugin-api-version": "2.6.0" "plugin-api-version": "2.6.0"
} }
+1 -1
View File
@@ -183,7 +183,7 @@ INTRO
// For example, if your logo is in public/img: // For example, if your logo is in public/img:
// - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs) // - 'logo' => '../img/logo.png' // for `static` type (output folder is public/docs)
// - 'logo' => 'img/logo.png' // for `laravel` type // - 'logo' => 'img/logo.png' // for `laravel` type
'logo' => false, 'logo' => 'img/logo-light.svg',
// Customize the "Last updated" value displayed in the docs by specifying tokens and formats. // Customize the "Last updated" value displayed in the docs by specifying tokens and formats.
// Examples: // Examples:
+1
View File
@@ -0,0 +1 @@
{"USD":{"Name":"US DOLLAR","Buying":39.6792,"Selling":39.7506,"Change":0,"Type":"Currency"},"AUD":{"Name":"AUSTRALIAN DOLLAR","Buying":25.967,"Selling":26.1363,"Change":0,"Type":"Currency"},"DKK":{"Name":"DANISH KRONE","Buying":6.2523,"Selling":6.2831,"Change":0,"Type":"Currency"},"EUR":{"Name":"EURO","Buying":46.7222,"Selling":46.8064,"Change":0,"Type":"Currency"},"GBP":{"Name":"POUND STERLING","Buying":54.1032,"Selling":54.3853,"Change":0,"Type":"Currency"},"CHF":{"Name":"SWISS FRANK","Buying":49.8917,"Selling":50.212,"Change":0,"Type":"Currency"},"SEK":{"Name":"SWEDISH KRONA","Buying":4.1341,"Selling":4.1769,"Change":0,"Type":"Currency"},"CAD":{"Name":"CANADIAN DOLLAR","Buying":29.1614,"Selling":29.293,"Change":0,"Type":"Currency"},"KWD":{"Name":"KUWAITI DINAR","Buying":129.2622,"Selling":130.9536,"Change":0,"Type":"Currency"},"NOK":{"Name":"NORWEGIAN KRONE","Buying":3.9292,"Selling":3.9556,"Change":0,"Type":"Currency"},"SAR":{"Name":"SAUDI RIYAL","Buying":10.5802,"Selling":10.5992,"Change":0,"Type":"Currency"},"JPY":{"Name":"JAPENESE YEN","Buying":0.2742,"Selling":0.276,"Change":0,"Type":"Currency"},"BGN":{"Name":"BULGARIAN LEV","Buying":23.7551,"Selling":24.0659,"Change":0,"Type":"Currency"},"RON":{"Name":"NEW LEU","Buying":9.183,"Selling":9.3032,"Change":0,"Type":"Currency"},"RUB":{"Name":"RUSSIAN ROUBLE","Buying":0.5007,"Selling":0.5073,"Change":0,"Type":"Currency"},"CNY":{"Name":"CHINESE RENMINBI","Buying":5.5081,"Selling":5.5802,"Change":0,"Type":"Currency"},"PKR":{"Name":"PAKISTANI RUPEE","Buying":0.139,"Selling":0.1408,"Change":0,"Type":"Currency"},"QAR":{"Name":"QATARI RIAL","Buying":10.8255,"Selling":10.9671,"Change":0,"Type":"Currency"},"KRW":{"Name":"SOUTH KOREAN WON","Buying":0.0289,"Selling":0.0293,"Change":0,"Type":"Currency"},"AZN":{"Name":"AZERBAIJANI NEW MANAT","Buying":23.2099,"Selling":23.5136,"Change":0,"Type":"Currency"},"AED":{"Name":"UNITED ARAB EMIRATES DIRHAM","Buying":10.7422,"Selling":10.8828,"Change":0,"Type":"Currency"}}
+48
View File
@@ -0,0 +1,48 @@
version: '3'
services:
app:
build:
context: .
dockerfile: dockerfile
image: truncgil-finance-app:latest
container_name: truncgil-finance-app
restart: always
volumes:
- .:/var/www
networks:
- app-network
web:
image: nginx:alpine
container_name: truncgil-finance-web
restart: always
ports:
- "8089:80"
volumes:
- .:/var/www
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
networks:
- app-network
db:
image: mysql:8.0
container_name: truncgil-finance-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: truncgil_finance
MYSQL_USER: truncgil_finance
MYSQL_PASSWORD: "QWEFaca123++"
volumes:
- db_data:/var/lib/mysql
networks:
- app-network
ports:
- "3308:3306"
networks:
app-network:
driver: bridge
volumes:
db_data:
View File
Executable
+73
View File
@@ -0,0 +1,73 @@
# Laravel için PHP 8.2 resmi imajını kullanıyoruz
FROM php:8.2-fpm
# Çalışma dizinini belirleyelim
WORKDIR /var/www
# Gerekli bağımlılıkları yükleyelim
RUN apt-get update && apt-get install -y \
git \
unzip \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
cron \
&& service cron start && \
docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd \
&& echo "* * * * * cd /var/www && php /var/www/artisan run-all-fetchs >> /dev/null 2>&1" >> /etc/cron.d/laravel-cron \
&& chmod 0644 /etc/cron.d/laravel-cron \
&& crontab /etc/cron.d/laravel-cron
# Composer'ı yükleyelim
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Laravel proje dosyalarını kopyalayalım
COPY . .
# Gerekli dizinleri oluşturma
RUN mkdir -p /var/www/storage/app/private/scribe
# Start of Selection
RUN set -x && \
echo "Dosya izinleri ayarlanıyor..." && \
chown -R www-data:www-data /var/www && \
echo "chown komutu tamamlandı" && \
find /var/www -type d -exec chmod 775 {} \; && \
echo "Dizin izinleri ayarlandı" && \
find /var/www -type f -exec chmod 664 {} \; && \
echo "Dosya izinleri ayarlandı" && \
chmod -R 775 /var/www/storage && \
echo "Storage izinleri ayarlandı" && \
chmod -R 775 /var/www/bootstrap/cache && \
echo "Cache izinleri ayarlandı" && \
chmod -R 775 /var/www/storage/framework/views && \
echo "Views izinleri ayarlandı" && \
chmod -R 775 /var/www/public && \
echo "Public dizin izinleri ayarlandı"
# Laravel uygulamasını başlatma ve loglama
RUN set -x && \
# echo "Laravel kurulum komutları başlatılıyor..." && \
# php artisan migrate && \
# echo "Migrasyon tamamlandı" && \
php artisan key:generate && \
echo "Uygulama anahtarı oluşturuldu" && \
php artisan config:cache && \
echo "Konfigürasyon önbelleğe alındı" && \
php artisan route:cache && \
echo "Rotalar önbelleğe alındı" && \
php artisan view:cache && \
echo "Görünümler önbelleğe alındı" && \
php artisan storage:link && \
echo "Storage sembolik bağlantısı oluşturuldu" && \
php artisan scribe:generate && \
echo "API dokümantasyonu oluşturuldu" && \
echo "Laravel uygulaması başarıyla başlatıldı.";
RUN service cron start && \
echo "Cron başlatıldı"
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

+65
View File
@@ -0,0 +1,65 @@
server {
listen 80; # 88 yerine 80 kullanın
server_name localhost;
root /var/www/public;
index index.php index.html;
# Keep-alive ve connection ayarları (bağlantı birikmesini önlemek için)
keepalive_timeout 65;
keepalive_requests 100;
client_max_body_size 20M;
client_body_timeout 60s;
client_header_timeout 60s;
send_timeout 60s;
# HTTPS için proxy headers
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
# Güvenlik başlıkları
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# Ana location
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP dosyaları için
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# HTTPS için ek parametreler
fastcgi_param HTTPS on;
fastcgi_param HTTP_X_FORWARDED_PROTO https;
# Timeout ayarları
fastcgi_read_timeout 300;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 300;
# FastCGI keep-alive ve buffer ayarları (bağlantı birikmesini önlemek için)
fastcgi_keep_conn on;
fastcgi_buffering on;
fastcgi_buffer_size 4k;
fastcgi_buffers 8 4k;
fastcgi_busy_buffers_size 8k;
# Connection pool ayarları
fastcgi_max_temp_file_size 0;
}
# Gizli dosyaları engelle
location ~ /\.ht {
deny all;
}
# Log dosyalarını engelle
location ~ /\.log {
deny all;
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 1.1 KiB

+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 877 968"><g clip-path="url(#a)"><circle cx="391" cy="391" r="390.5" stroke="#009846" transform="matrix(-1 0 0 1 416 -56)" /><circle cx="468" cy="468" r="467.5" stroke="#009846" opacity=".3" transform="matrix(-1 0 0 1 493 -133)"/><circle cx="558" cy="558" r="557.5" stroke="#009846" opacity=".1" transform="matrix(-1 0 0 1 583 -223)" /><g filter="url(#b)"> <ellipse cx="583" cy="229.5" fill="#009846" rx="583" ry="229.5" transform="matrix(-1 0 0 1 621 -9)" /></g><g filter="url(#c)"><ellipse cx="262" cy="184.5" fill="#fff" rx="262" ry="184.5" transform="matrix(-1 0 0 1 99 42)" /></g></g><defs><filter id="b" width="1614" height="907" x="-769" y="-233" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix" /><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" /><feGaussianBlur result="effect1_foregroundBlur_3089_39042" stdDeviation="112" /></filter><filter id="c" width="972" height="817" x="-649" y="-182" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse"><feFlood flood-opacity="0" result="BackgroundImageFix" /><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape" /><feGaussianBlur result="effect1_foregroundBlur_3089_39042" stdDeviation="112" /></filter><clipPath id="a"><path fill="#fff" d="M877 0H0v968h877z" /></clipPath></defs></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

+52
View File
@@ -0,0 +1,52 @@
{
"name": "Truncgil Finance API",
"short_name": "Truncgil Finance",
"theme_color": "#009846",
"background_color": "#009846",
"display": "browser",
"orientation": "portrait",
"scope": "https://finance.truncgil.com/",
"start_url": "https://finance.truncgil.com/",
"icons": [
{
"src": "img/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "img/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "img/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "img/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "img/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "img/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "img/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "img/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
+32
View File
@@ -0,0 +1,32 @@
@if($rate)
<div class="card">
<div class="title">
<p class="title-text">
{{$currencyName}}
</p>
<p class="percent" style="color: {{ ($rate['Change'] ?? 0) > 0 ? 'green' : '#B9101E' }}">
{{ $rate['Change'] ?? 0 }}%
</p>
@if(($rate['Change'] ?? 0) > 0)
<svg width="20" height="20" fill="green" style="position: relative; top: -2px;" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg" transform="rotate(180)"> <path d="M384 576q0-26 19-45t45-19h896q26 0 45 19t19 45-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45z"></path> </svg>
@else
<svg width="20" height="20" fill="#B9101E" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> <path d="M384 576q0-26 19-45t45-19h896q26 0 45 19t19 45-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45z"></path> </svg>
@endif
</p>
</div>
<div class="data">
<p>
{{$rate['Selling'] ?? '0.00'}}
</p>
<div class="range">
<div class="fill" style="background-color: {{ ($rate['Change'] ?? 0) > 0 ? 'green' : '#B9101E' }};">
</div>
</div>
</div>
</div>
@endif
+39 -5
View File
@@ -1,21 +1,44 @@
<!-- See https://github.com/stoplightio/elements/blob/main/docs/getting-started/elements/elements-options.md for config --> <!-- See https://github.com/stoplightio/elements/blob/main/docs/getting-started/elements/elements-options.md for config -->
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en" class="dark">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>{!! $metadata['title'] !!}</title> <title>{!! $metadata['title'] !!}</title>
<!-- Embed elements Elements via Web Component --> <!-- Embed elements Elements via Web Component -->
<script src="https://unpkg.com/@stoplight/elements/web-components.min.js"></script> <script src="https://unpkg.com/@stoplight/elements@9.0.0/web-components.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@stoplight/elements/styles.min.css"> <link rel="stylesheet" href="https://unpkg.com/@stoplight/elements@9.0.0/styles.min.css">
<style> <style>
body { body {
height: 100vh; height: 100vh;
} }
elements-api {
--elements-border-radius: 6px;
}
.sl-inline img {
width: 400px;
margin: 0 auto;
display: block;
}
.sl-prose p {
font-size: var(--fs-paragraph);
margin-bottom: 1em;
margin-top: 1em;
}
.sl-text-base {
font-size: 16px;
}
h4.sl-text-paragraph.sl-leading-snug.sl-font-prose.sl-font-semibold.sl-text-heading {
display: none;
}
</style> </style>
</head> </head>
<body> <body>
<elements-api <elements-api
@foreach($htmlAttributes as $attribute => $value) @foreach($htmlAttributes as $attribute => $value)
{{-- Attributes specified first override later ones --}} {{-- Attributes specified first override later ones --}}
@@ -23,12 +46,23 @@
@endforeach @endforeach
apiDescriptionUrl="{!! $metadata['openapi_spec_url'] !!}" apiDescriptionUrl="{!! $metadata['openapi_spec_url'] !!}"
router="hash" router="hash"
layout="sidebar" layout="responsive"
appearance="auto"
hideTryIt="{!! ($tryItOut['enabled'] ?? true) ? '' : 'true'!!}" hideTryIt="{!! ($tryItOut['enabled'] ?? true) ? '' : 'true'!!}"
@if(!empty($metadata['logo'])) @if(!empty($metadata['logo']))
logo="{!! $metadata['logo'] !!}" logo="{!! $metadata['logo'] !!}"
@endif @endif
/> />
<script>
setTimeout(function() {
const linkElement = document.querySelector('a.sl-flex.sl-items-center.sl-px-4.sl-py-3.sl-border-t');
if (linkElement) {
linkElement.href = "https://truncgil.com"; // Yeni URL'yi buraya ekleyin
linkElement.innerHTML = '<img src="https://truncgil.com.tr/yatay.svg" width="100" alt="Truncgil Teknoloji">'; // Resim URL'sini ve alternatif metni buraya ekleyin
}
}, 1000); // 1 saniye gecikme
</script>
</body> </body>
</html> </html>
File diff suppressed because one or more lines are too long
Executable
+32
View File
@@ -0,0 +1,32 @@
#!/bin/bash
# Proje dizinine git
cd "$(dirname "$0")"
# Proje adını tanımlayalım
PROJECT_NAME="finance"
DB_PORT="3308"
echo "🚀 '$PROJECT_NAME' projesi kontrol ediliyor..."
# 1. Port çakışmasını kontrol et ve temizle
echo "🔍 Port $DB_PORT kontrol ediliyor..."
CONFLICTING_CONTAINER=$(docker ps -q --filter "publish=$DB_PORT")
if [ ! -z "$CONFLICTING_CONTAINER" ]; then
echo "⚠️ Port $DB_PORT, $(docker ps --filter "id=$CONFLICTING_CONTAINER" --format "{{.Names}}") tarafından kullanılıyor. Temizleniyor..."
docker rm -f "$CONFLICTING_CONTAINER"
fi
# 2. İsim çakışmalarını temizle
echo "🧹 İsim çakışmaları temizleniyor..."
docker rm -f truncgil-finance-app truncgil-finance-web truncgil-finance-db 2>/dev/null
# 3. Servisleri başlat
echo "🆙 Servisler başlatılıyor..."
docker compose -p "$PROJECT_NAME" up -d --remove-orphans
# Durumu göster
echo "📊 Mevcut durum ($PROJECT_NAME):"
docker compose -p "$PROJECT_NAME" ps
echo "✅ '$PROJECT_NAME' projesi başarıyla ayağa kaldırıldı!"
+10 -2
View File
@@ -3,14 +3,14 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use App\Http\Controllers\CurrencyController; use App\Http\Controllers\CurrencyController;
use App\Http\Controllers\TimeDateController;
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| API Routes | API Routes
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
*/ */
Route::get('/run-all-fetchs', [CurrencyController::class, 'runAllFetchs']);
//Route::get('/run-all-fetchs', [CurrencyController::class, 'runAllFetchs']);
Route::get('/today.json', [CurrencyController::class, 'getAllRates']); Route::get('/today.json', [CurrencyController::class, 'getAllRates']);
@@ -19,3 +19,11 @@ Route::get('/currency-rates/{currencyName}', [CurrencyController::class, 'getCur
Route::get('/gold-rates', [CurrencyController::class, 'getGoldRates']); Route::get('/gold-rates', [CurrencyController::class, 'getGoldRates']);
Route::get('/gold-rates/{goldName}', [CurrencyController::class, 'getGoldRateByName']); Route::get('/gold-rates/{goldName}', [CurrencyController::class, 'getGoldRateByName']);
Route::get('/crypto-currency-rates', [CurrencyController::class, 'getCryptoCurrencyRates']);
Route::get('/crypto-currency-rates/{cryptoCurrencyName}', [CurrencyController::class, 'getCryptoCurrencyRateByName']);
Route::get('/server-time', [TimeDateController::class, 'getServerTime']);
Route::get('/server-date', [TimeDateController::class, 'getServerDate']);
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
View File
View File
View File
View File
Regular → Executable
View File