Compare commits

...

1 commit

Author SHA1 Message Date
e8fc4ce653
refac: use vuepress 2024-07-24 17:50:51 +03:00
82 changed files with 5689 additions and 40 deletions

21
.gitignore vendored
View file

@ -1,6 +1,17 @@
# misc # editors
.DS_Store .idea/
.vscode/
*.swp
# direnv # direnv
/.envrc .direnv
/.direnv/ .envrc
# nodejs
node_modules/
# nix
/result
# custom
.DS_Store
# vuepress
docs/.vuepress/.cache
docs/.vuepress/.temp
docs/.vuepress/dist

View file

@ -1,13 +1,14 @@
PAR := $(MAKE) -j 128 NPM ?= npm
watch:
${PAR} deno-w sass-w
deno-w:
deno run -A --watch server.ts
sass-w:
sass -w styles/main.scss public/styles/main.css
help: help:
cat makefile cat makefile
build:
$(NPM) run docs:build
dev:
$(NPM) run docs:dev
deps:
$(NPM) install

6
docs/.vuepress/client.ts Normal file
View file

@ -0,0 +1,6 @@
import { defineClientConfig } from "vuepress/client";
import WorksPage from "./pages/WorksPage.vue";
export default defineClientConfig({
layouts: { WorksPage },
});

84
docs/.vuepress/config.ts Normal file
View file

@ -0,0 +1,84 @@
import { defineUserConfig } from "vuepress";
import { viteBundler } from "@vuepress/bundler-vite";
import { mkMyTheme } from "./theme.js";
import { redirectPlugin } from "@vuepress/plugin-redirect";
export default defineUserConfig({
lang: "ru-RU",
title: "Дмитрий Плешевский",
description: " ",
locales: {
"/": {
lang: "ru-RU",
title: "Дмитрий Плешевский",
},
"/eng/": {
lang: "en-US",
title: "Dmitriy Pleshevskiy",
},
},
theme: mkMyTheme({
hostname: "https://pleshevski.ru",
repo: "https://git.pleshevski.ru/pleshevskiy/pleshevski.ru",
locales: {
"/": {
selectLanguageName: "Русский",
navbar: ["/", "/works"],
notFound: [
"Верните страницу!",
"Мы потеряли страницу...",
"Вы заблокированы в лабиринте.",
"Искали кота?",
"Страница украдена.",
"Ошиблись в параллельной вселенной.",
],
backToHome: "Вернуться на главную",
worksTable: {
name: "Название",
description: "Описание",
role: "Роль",
technologies: "Технологии",
start: "Начало",
statusOrEnd: "Статус/Окончание",
},
},
"/eng/": {
selectLanguageName: "English",
navbar: ["/eng/", "/eng/works"],
notFound: [
"Return the page!",
"We lost a page...",
"You're blocked in a labyrinth.",
"Looking for a cat?",
"The page has been stolen.",
"Wrong turn in parallel universe.",
],
backToHome: "Back to home",
worksTable: {
name: "Name",
description: "Description",
role: "Role",
technologies: "Technologies",
start: "Start",
statusOrEnd: "Status/End",
},
},
},
}),
plugins: [
redirectPlugin({
config: {
"/rus/": "/",
"/rus/works.html": "/works.html",
},
}),
],
bundler: viteBundler(),
});

9
docs/.vuepress/global.ts Normal file
View file

@ -0,0 +1,9 @@
export type NonEmptyArray<T> = [T, ...T[]];
export function renderDate(date: Date): string {
return date.toLocaleDateString(undefined, {
year: "numeric",
month: "2-digit",
day: "2-digit",
});
}

View file

@ -0,0 +1,44 @@
<script lang="ts">
export default {
name: 'WorksPage',
computed: {
tableTheme() {
return this.$themeLocale.worksTable ?? {};
},
},
}
</script>
<script lang="ts" setup>
import { CHRONOLOGICAL_WORKS } from '../data.ts'
import { renderDate } from '../../../global.ts'
import { work as w } from '../domain'
</script>
<template>
<table>
<thead>
<tr>
<th>{{ tableTheme.name }}</th>
<th>{{ tableTheme.description }}</th>
<th>{{ tableTheme.role }}</th>
<th>{{ tableTheme.technologies }}</th>
<th>{{ tableTheme.start }}</th>
<th>{{ tableTheme.statusOrEnd }}</th>
</tr>
</thead>
<tbody>
<tr v-for="work in CHRONOLOGICAL_WORKS">
<td><a rel="nofollow noopener" :href="w.getExternalLink(work)">{{ work.name }}</a></td>
<td>{{ work.description }}</td>
<td v-html="work.roles.join(', ')"></td>
<td>{{ work.technologies.join(', ') }}</td>
<td>{{ renderDate(work.startDate) }}</td>
<td>{{ work.endDate ? renderDate(work.endDate) : work.status }}</td>
</tr>
</tbody>
</table>
</template>

View file

@ -0,0 +1 @@
export { default as ChronologicalWorksTable } from "./ChronologicalWorksTable.vue";

View file

@ -0,0 +1,361 @@
import { Role } from "./domain/Role.ts";
import { Status } from "./domain/Status.ts";
import { Technology } from "./domain/Technology.ts";
import type { Work } from "./domain/Work.ts";
export const CHRONOLOGICAL_WORKS: Work[] = [
{
name: "picsg",
url: "/pleshevskiy/picsg",
description:
"A tool for steganographing information in a picture encoded using the Vernam cipher.",
roles: [Role.Author],
technologies: [Technology.Haskell],
startDate: new Date("2024-04-13"),
status: Status.AsIs,
},
{
name: "Mindustry tools",
url: "/pleshevskiy/mindustry-tools",
description: "Tools for the Mindustry game",
roles: [Role.Author],
technologies: [Technology.Nix, Technology.Godot],
startDate: new Date("2024-01-07"),
status: Status.PassivelyMaintained,
},
{
name: "Master Progress Rosmintrud tools",
url: "https://rosmintrud.masterprogress.ru",
description:
"Internal service to prepare documents for the rosmintrud (SPA)",
roles: [Role.TechLead],
technologies: [
Technology.Deno,
Technology.Sqlite,
Technology.TypeScript,
Technology.Vue,
Technology.Docker,
Technology.Woodpecker,
Technology.Nix,
],
startDate: new Date("2023-07-03"),
status: Status.PassivelyMaintained,
},
{
name: "yandexgpt_tg_bot",
url: "/pleshevskiy/yandexgpt_tg_bot",
description: "The Telegram bot to describe article with link by YandexGPT.",
roles: [Role.Author],
technologies: [Technology.JavaScript, Technology.NodeJS, Technology.Nix],
startDate: new Date("2023-06-27"),
status: Status.PassivelyMaintained,
},
{
name: "tree-sitter-plpgsql",
url: "/pleshevskiy/tree-sitter-plpgsql",
description: "plpgsql grammar for tree-sitter",
roles: [Role.Author],
technologies: [
Technology.C,
Technology.JavaScript,
Technology.TreeSitter,
Technology.Nix,
],
startDate: new Date("2023-01-05"),
status: Status.PassivelyMaintained,
},
{
name: "wd2",
url: "/pleshevskiy/wd2",
description:
"A wrapper over d2 which allows to use additional configs from d2 file",
roles: [Role.Author],
technologies: [Technology.Bash, Technology.Nix],
startDate: new Date("2022-12-12"),
endDate: new Date("2023-07-31"),
status: Status.AsIs,
},
{
name: "tree-sitter-d2",
url: "/pleshevskiy/tree-sitter-d2",
description: "d2 grammar for tree-sitter",
roles: [Role.Author],
technologies: [
Technology.C,
Technology.JavaScript,
Technology.TreeSitter,
Technology.Nix,
],
startDate: new Date("2022-12-04"),
status: Status.ActiveDeveloped,
},
{
name: "nix2lua",
url: "/mynix/nix2lua",
description:
"This is a small but functional library that converts your nix configurations into lua format.",
roles: [Role.Author],
technologies: [Technology.Nix, Technology.Lua],
startDate: new Date("2022-11-22"),
status: Status.PassivelyMaintained,
},
{
name: "vnetod",
url: "/pleshevskiy/vnetod",
description: "Dotenv section switcher",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-07-29"),
status: Status.PassivelyMaintained,
},
{
name: "estring",
url: "/pleshevskiy/estring",
description: "A simple way to parse a string using type annotations.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-07-23"),
status: Status.PassivelyMaintained,
},
{
name: "enve",
url: "/pleshevskiy/enve",
description:
"It helps you work with environment variables and convert it to any type using only type annotations",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-07-18"),
status: Status.PassivelyMaintained,
},
{
name: "docker stack drone plugin",
url: "/drone_plugins/docker_stack",
description: "Deploy to production using `docker stack deploy`",
roles: [Role.Author],
technologies: [Technology.Docker, Technology.Drone, Technology.Woodpecker],
startDate: new Date("2022-06-06"),
status: Status.PassivelyMaintained,
},
{
name: "dexios",
url: "/github/dexios",
description:
"Dexios is a fast, secure, and open source command-line encryption tool.",
roles: [Role.Collaborator],
technologies: [Technology.Rust],
startDate: new Date("2022-06-01"),
endDate: new Date("2023-02-28"),
},
{
name: "recipes",
url: "/pleshevskiy/recipes",
description: "Site with recipes which cares about privacy",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.Deno, Technology.Rust],
startDate: new Date("2022-05-04"),
status: Status.PassivelyMaintained,
},
{
name: "pleshevski.ru",
url: "/pleshevskiy/pleshevski.ru",
description: "Source code of my personal site",
roles: [Role.Author],
technologies: [
Technology.TypeScript,
Technology.Deno,
Technology.Docker,
Technology.Woodpecker,
],
startDate: new Date("2022-03-16"),
status: Status.PassivelyMaintained,
},
{
name: "paren",
url: "/pleshevskiy/paren",
description: "Library for parsing and rendering information.",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.Deno],
startDate: new Date("2022-03-14"),
status: Status.Experimental,
},
{
name: "hwt",
url: "/pleshevskiy/hwt",
description:
"healthy workaholic timer A tool that keeps you from breaking your health by working all day.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2022-02-04"),
status: Status.AsIs,
},
{
name: "ood_persistence",
url: "/pleshevskiy/ood_persistence",
description:
"Asynchronous and synchronous interfaces and persistence implementations for your OOD architecture ",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2021-10-12"),
status: Status.Deprecated,
},
{
name: "migra",
url: "/pleshevskiy/migra",
description: "Simple SQL migration manager for your project.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2021-01-31"),
status: Status.AsIs,
},
{
name: "espruino-starter",
url: "/pleshevskiy/espruino-starter",
description:
"Quickly start creating your new project on the espruino board or a board based on it.",
roles: [Role.Author],
technologies: [Technology.JavaScript],
startDate: new Date("2021-08-23"),
status: Status.AsIs,
},
{
name: "react-rest-request",
url: "/pleshevskiy/react-rest-request",
description: "Minimalistic REST API client for React inspired by Apollo.",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.React],
startDate: new Date("2020-10-04"),
status: Status.Deprecated,
},
{
name: "sonic-channel",
url: "/pleshevskiy/sonic-channel",
description: "Rust client for sonic search backend.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2020-07-18"),
status: Status.PassivelyMaintained,
},
{
name: "itconfig",
url: "/pleshevskiy/itconfig",
description:
"Easy build a configs from environment variables and use it in globally.",
roles: [Role.Author],
technologies: [Technology.Rust],
startDate: new Date("2019-12-22"),
status: Status.Deprecated,
},
{
name: "it-fsm",
url: "/pleshevskiy/it-fsm",
description: "Simple full-featured finite state machine for your project",
roles: [Role.Author],
technologies: [Technology.TypeScript, Technology.NodeJS, Technology.Deno],
startDate: new Date("2019"),
status: Status.PassivelyMaintained,
},
{
name: "Cabinet Master Progress",
url: "https://cabinet.masterprogress.ru",
description:
"Student's cabinet of the educational center Master Progress (SSR + SPA)",
roles: [Role.TechLead],
technologies: [
Technology.Python,
Technology.Flask,
Technology.Postgresql,
Technology.TypeScript,
Technology.React,
Technology.Docker,
Technology.Woodpecker,
Technology.Nix,
],
startDate: new Date("2019-09-22"),
status: Status.PassivelyMaintained,
},
{
name: "genrss",
url: "/pleshevskiy/genrss",
description: "RSS generator for python",
roles: [Role.Author],
technologies: [Technology.Python],
startDate: new Date("2019-07-23"),
status: Status.AsIs,
},
{
name: "marshmallow_pageinfo",
url: "/pleshevskiy/marshmallow_pageinfo",
description: "Page info marshmallow schema for api",
roles: [Role.Author],
technologies: [Technology.Python],
startDate: new Date("2019-10-05"),
status: Status.AsIs,
},
{
name: "Binary Management",
url: "https://www.binarymanagement.com",
description: "Project management tool for interior designers",
roles: [Role.Developer, Role.TechLead, Role.TeamLead],
technologies: [
Technology.TypeScript,
Technology.NodeJS,
Technology.React,
Technology.Antd,
Technology.Docker,
Technology.Drone,
Technology.Rust,
Technology.Nix,
],
startDate: new Date("2018-09-15"),
status: Status.ActiveDeveloped,
},
{
name: "Core Spirit",
url: "https://corespirit.com",
description: "Social platform focusing on human and planetary enhancement",
roles: [Role.Developer],
technologies: [
Technology.TypeScript,
Technology.NodeJS,
Technology.React,
Technology.Docker,
Technology.Drone,
],
startDate: new Date("2018-09-05"),
endDate: new Date("2019-12-31"),
},
{
name: "Master Progress",
url: "https://masterprogress.ru",
description:
"Main website of the educational center Master Progress (SSR + Forms)",
roles: [Role.TechLead],
technologies: [
Technology.Python,
Technology.Flask,
Technology.JavaScript,
Technology.Docker,
Technology.Woodpecker,
],
startDate: new Date("2018-04-10"),
status: Status.PassivelyMaintained,
},
{
name: "ictmpl",
url: "/pleshevskiy/ictmpl",
description: "Generate projects from templates",
roles: [Role.Author],
technologies: [Technology.Python],
startDate: new Date("2018-06-30"),
status: Status.AsIs,
},
{
name: "jjcrypto",
url: "/pleshevskiy/jjcrypto",
description: "Javascript encoder and decoder",
roles: [Role.Author],
technologies: [Technology.Php],
startDate: new Date("2015-11-01"),
status: Status.AsIs,
},
];

View file

@ -0,0 +1,20 @@
import type { NonEmptyArray } from "../../../global.ts";
import { Role } from "./Role.ts";
import { Status } from "./Status.ts";
import { Technology } from "./Technology.ts";
export interface Work {
name: string;
url: string;
description: string;
roles: NonEmptyArray<Role>;
technologies: NonEmptyArray<Technology>;
startDate: Date;
endDate?: Date;
status?: Status;
}
export const getExternalLink: (work: Pick<Work, "url">) => string = (work) =>
work.url.startsWith("https://")
? work.url
: new URL(work.url, "https://git.pleshevski.ru").toString();

View file

@ -0,0 +1 @@
export * from "./ChronologicalWorksTable";

View file

@ -0,0 +1,42 @@
<script setup>
// See: https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/theme-default/layouts/Layout.vue
import ParentLayout from '@vuepress/theme-default/layouts/Layout.vue'
import { ChronologicalWorksTable } from "../modules/work";
</script>
<template>
<ParentLayout>
<template #page-bottom>
<div class="works-table-wrapper">
<ChronologicalWorksTable />
</div>
</template>
</ParentLayout>
</template>
<style lang="css" scoped>
.works-table-wrapper {
margin: 0 auto;
padding: 0 2rem;
max-width: 1224px;
box-sizing: border-box
}
.works-table-wrapper :deep(table) {
width: 100%;
}
</style>
<style lang="css">
:root {
--content-width: 960px;
}
.vp-page .theme-default-content {
padding-bottom: 0 !important;
}
.vp-page-meta {
display: none;
}
</style>

10
docs/.vuepress/theme.ts Normal file
View file

@ -0,0 +1,10 @@
import { defaultTheme } from '@vuepress/theme-default'
export const mkMyTheme = (options) => {
// returns a theme object
return {
name: 'my-theme',
extends: defaultTheme(options),
}
}

109
docs/eng/index.md Normal file
View file

@ -0,0 +1,109 @@
---
home: true
title: Resume
heroText: null
---
Always up-to-date link to [resume](/eng/).
### Overview
My name is Dmitriy Pleshevskiy.
I'm an open source software enthusiast, a lead software developer, architect,
team leader and also mentor.
### Skills
Programming Languages:
- TypeScript (prefer, solid 9-year exp)
- SQL (prefer, solid 8-year exp)
- Rust (prefer, solid 5-year exp)
- Python (solid 9-year exp)
- Haskell
- Bash
- Java
- C#
- C++
Databases:
- PostgreSQL (prefer, solid 7-year exp)
- MySQL
- Sqlite
- MsSQL
- MongoDB
- Reddis
I also have extensive experience in creating the following applications:
- Traditional (SSR + Forms)
- API (REST/GraphQL/WebSocket/EventSource)
- Dynamic (SPA)
- Hybrid (SSR + SPA)
- Console
- Crossplatform
### Stack
Backend (Rust)
- axum (prefer, solid 2-year exp)
- async-graphql (prefer, solid 2-year exp)
- shaku (prefer, solid 2-year exp)
- bb8 + postgres-types (prefer, solid 5-year exp)
- diesel (2-year exp)
Backend (Node.JS)
- Apollo (solid 5-year exp)
- Express (solid 9-year exp)
- Nest.JS
- Knex.js / Objection.js (solid 5-year exp)
- Sequelize
Frontend
- React (solid 8-year exp)
- VueJS (prefer, solid 3-year exp)
- Cypress (prefer, solid 3-year exp)
- JQuery
- Antd / Antdv
- PostCSS (prefer, solid 5-year exp)
- Sass (prefer, solid 8-year exp)
- Less (weak 4-year exp)
DevOps
- NixOS / NixOps / Nix dev shell (prefer, solid 2-year exp)
- Docker Swarm (prefer, solid 5-year exp)
- Kubernetes (weak 4-year exp)
- Woodpecker CI (prefer, solid 3-year exp)
- Drone CI (solid 3-year exp)
- Gitlab CI (solid 7-year exp)
- GitHub Actions (3-year exp)
### Interests
Open-source projects are my passion! I develop, maintain and improve projects in
my spare time.
Besides programming, I love to cook and spend time with my beloved family!
### Contacts
SimpleX:
[Dmitriy Pleshevskiy](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2FSkIkI6EPd2D63F4xFKfHk7I1UGZVNn6k1QWZ5rcyr6w%3D%40smp9.simplex.im%2FLfKyG0YgW5eRO-z8vrEyvnNfV2EKDfBv%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAMRpR3YB10GVzc-asfqY2oIFkipx5RQm4DZRabzjfPHo%253D%26srv%3Djssqzccmrcws6bhmn77vgmhfjmhwlyr3u7puw4erkyoosywgl67slqqd.onion)
Telegram: [Dmitriy Pleshevskiy](https://telegram.me/da_pranaya)
Matrix: @pleshevskiy:matrix.org
Email: dmitriy[at]pleshevski[dot]ru
### Links
[My Git Repo](https://git.pleshevski.ru/)
[My Github (Suspended due to sanctions)](https://github.com/pleshevskiy)

71
docs/eng/works.md Normal file
View file

@ -0,0 +1,71 @@
---
title: Works
layout: WorksPage
sidebar: false
---
### Highlighted working experience
#### Binary Management
- Dates: August 2018 currently
- Roles: Lead Fullstack Developer, Team Lead, Architect
Development of a project management tool for interior designers
- Development of the GraphQL API (Node.JS, Apollo, PostgreSQL, Redis, BullMQ).
Moved database triggers to business logic. Wrote integration tests on 70% api.
- Development of the frontend (React, Antd). Formed uikit, shared components,
redesigned the page generation gathering. Completely changed work with API on
the frontend. Introduced the practice of writing integration tests using
cypress
- Completely ported the project to TypeScript. I have formed isolated modules of
the system.
- As a team leader, I brought the critical chain method, the buffer method, and
the planning method to the project from the end. Helped the team get into a
rhythm to make releases each week in small batches. A couple of times I also
prepared an individual development plan for team members.
#### Master Progress
- Dates: May 2018 - currently (Passively maintained)
- Role: Tech Lead
Development web infrastructure of the educational center Master Progress
- [The main site](https://masterprogress.ru) (Python, Flask).
- [Student's cabinet](https://cabinet.masterprogress.ru) (Python,
Flask, TypeScript, React).
- [A tool for rosmintrud](https://rosmintrud.masterprogress.ru)
(Deno, Vue, Typescript)
- Created a complete infrastructure on Woodpecker CI and Docker swarm.
#### Core Spirit
- Dates: August 2018 - May 2020
- Role: Lead Fullstack Developer
Development of Social platform focusing on human and planetary enhancement.
- REST API (Node.JS, Express, PostgreSQL) for main site and
backoffice.
- Auto poster to various social networks and messengers
(Facebook, LinkedIn, Twitter, Telegram).
- Neural network for automatic categorization of articles.
#### MERLION
- Dates: March 2016 May 2018
- Role: Senior Fullstack developer
In this company there were 6 considerable projects I have successfully
completed:
- optimize the creation of promotional pages (PHP, JavaScript)
- support main traditional site <https://citilink.ru> (PHP, JavaScript)
- development of parsing to monitor products for changes in price,
quantity/availability in stock, rating and other fields based on data from 55
websites (Node.JS, Express)
- work with neural networks for matching of goods
- development face recognition apps for Android (Java)

111
docs/index.md Normal file
View file

@ -0,0 +1,111 @@
---
home: true
title: Резюме
heroText: null
---
Всегда актуальная ссылка на [резюме](/).
### Общие сведения
Меня зовут Дмитрий Плешевский.
Я энтузиаст программного обеспечения с открытым исходным кодом, ведущий
разработчик програмного обеспечения, архитектор, руководитель команды, а так же
ментор.
### Умения
Языки программирования:
- TypeScript (предпочитаю, твёрдый 9-летний опыт)
- SQL (предпочитаю, твёрдый 8-летний опыт)
- Rust (предпочитаю, 5-летний опыт)
- Python (твёрдый 9-летний опыт)
- Haskell
- Bash
- Java
- C#
- C++
Базы данных:
- PostgreSQL (предпочитаю, твёрдый 7-летний опыт)
- MySQL
- Sqlite
- MsSQL
- MongoDB
- Reddis
Я так же имею большой опыт в создании следующих типов приложений:
- Традиционные (SSR + Forms)
- API (REST/GraphQL/WebSocket/EventSource)
- Динамическое (SPA)
- Гибридное (SSR + SPA)
- Консольные
- Кроссплатформенные
### Stack
Backend (Rust)
- axum (предпочитаю, твёрдый 2-летний опыт)
- async-graphql (предпочитаю, твёрдый 2-летний опыт)
- shaku (предпочитаю, твёрдый 2-летний опыт)
- bb8 + postgres-types (предпочитаю, твёрдый 5-летний опыт)
- diesel (2-летний опыт)
Backend (Node.JS)
- Apollo (твёрдый 5-летний опыт)
- Express (твёрдый 9-летний опыт)
- Nest.JS
- Knex.js / Objection.js (твёрдый 5-летний опыт)
- Sequelize
Frontend
- React (твёрдый 8-летний опыт)
- VueJS (предпочитаю, твёрдый 4-летний опыт)
- Cypress (предпочитаю, твёрдый 3-летний опыт)
- JQuery
- Antd / Antdv
- PostCSS (предпочитаю, твёрдый 5-летний опыт)
- Sass (предпочитаю, твёрдый 8-летний опыт)
- Less (слабый 4-летний опыт)
DevOps
- NixOS / NixOps / Nix dev shell (предпочитаю, твёрдый 2-летний опыт)
- Docker Swarm (предпочитаю, твёрдый 5-летний опыт)
- Kubernetes (слабый 4-летний опыт)
- Woodpecker CI (предпочитаю, твёрдый 3-летний опыт)
- Drone CI (твёрдый 3-летний опыт)
- Gitlab CI (твёрдый 7-летний опыт)
- GitHub Actions (3-летний опыт)
### Интересы
Open-source проекты - моя страсть! Разрабатываю, поддерживаю и улучшаю проекты в
своё свободное время.
Помимо программирования я люблю готовить и проводить время со своей любимой
семьей!
### Контакты
SimpleX:
[Dmitriy Pleshevskiy](https://simplex.chat/contact#/?v=1-2&smp=smp%3A%2F%2FSkIkI6EPd2D63F4xFKfHk7I1UGZVNn6k1QWZ5rcyr6w%3D%40smp9.simplex.im%2FLfKyG0YgW5eRO-z8vrEyvnNfV2EKDfBv%23%2F%3Fv%3D1-2%26dh%3DMCowBQYDK2VuAyEAMRpR3YB10GVzc-asfqY2oIFkipx5RQm4DZRabzjfPHo%253D%26srv%3Djssqzccmrcws6bhmn77vgmhfjmhwlyr3u7puw4erkyoosywgl67slqqd.onion)
Telegram: [Dmitriy Pleshevskiy](https://telegram.me/da_pranaya)
Matrix: @pleshevskiy:matrix.org
Email: dmitriy[at]pleshevski[dot]ru
### Ссылки
[My Git Repo](https://git.pleshevski.ru/)
[My Github (Приостановлен из-за санкций)](https://github.com/pleshevskiy)

75
docs/works.md Normal file
View file

@ -0,0 +1,75 @@
---
title: Работы
layout: WorksPage
sidebar: false
---
## Выделенный опыт работы
### Binary Management
- Даты: Август 2018 по настоящее время
- Роли: Lead Fullstack Developer, Team Lead, Architect
Разработка инструмента управления проектами для дизайнеров интерьера
- Разработка GraphQL API (Node.JS, Apollo, PostgreSQL, Redis, BullMQ). Перенес
триггеры базы данных в бизнес-логику. Написал интеграционные тесты на 70% api.
- Разработка фронтенда (React, Antd). Сформировал uikit и общие компоненты,
оптимизировал сложные и нагруженные компоненты. Полностью изменил работу с API
на фронтенде. Внедрил практику написания интеграционных тестов с помощью
cypress.
- Полностью перенес проект на TypeScript. Сформировал изолированные модули
системы.
- Как руководитель команды, я привнес в проект метод критической цепи, метод
буфера и метод планирования с конца. Помог команде войти в ритм, чтобы
выпускать релизы каждую неделю небольшими партиями. Я также несколько раз
составлял индивидуальный план развития для членов команды.
### Master Progress
- Даты: Май 2018 - по настоящее время (Пассивная поддержка)
- Роль: Tech Lead
Разработка веб-инфраструктуры образовательного центра Мастер Прогресс
- [Главного сайта](https://masterprogress.ru) (Python, Flask).
- [Кабинета студента](https://cabinet.masterprogress.ru) (Python, Flask,
TypeScript, React).
- [Инструмента для работы с rosmintrud](https://rosmintrud.masterprogress.ru)
(Deno, Vue, Typescript)
- Создана полная инфраструктура на Woodpecker CI и Docker swarm.
### Core Spirit
- Даты: Август 2018 - May 2020
- Роль: Lead Fullstack Developer
Разработка социальной платформы, сфокусированной на улучшении человека и
планеты.
- REST API (Node.JS, Express, PostgreSQL) для основного сайта и
бэк-офиса.
- Автопостер в различные социальные сети и мессенджеры (Facebook,
LinkedIn, Twitter, Telegram).
- Создал нейронную сеть для автоматической категоризации статей.
### MERLION
- Dates: March 2016 May 2018
- Role: Senior Fullstack developer
В этой компании было 6 значительных проектов, которые я успешно завершил:
- Оптимизация создания рекламных страниц (PHP, JavaScript)
- Поддержка основного традиционного сайта <https://citilink.ru> (PHP,
JavaScript)
- Разработка парсинга для мониторинга товаров на предмет изменения цены,
количества/наличия на складе, рейтинга и других полей на основе данных с 55+
сайтов (Node.js, Express)
- Работа с нейронными сетями для подбора товаров
- Разработка приложений для распознавания лиц для Android (Java)
## Хронология
В списке перечислены только публичные проекты.

View file

@ -1,12 +1,30 @@
{ {
"nodes": { "nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1654593855, "lastModified": 1721562059,
"narHash": "sha256-c+SyXvj7THre87OyIdZfRVR+HhI/g1ZDrQ3VUtTuHkU=", "narHash": "sha256-Tybxt65eyOARf285hMHIJ2uul8SULjFZbT9ZaEeUnP8=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "033bd4fa9a8fbe0c68a88e925d9a884161044b25", "rev": "68c9ed8bbed9dfce253cc91560bf9043297ef2fe",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -18,22 +36,22 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"nixpkgs": "nixpkgs", "flake-utils": "flake-utils",
"utils": "utils" "nixpkgs": "nixpkgs"
} }
}, },
"utils": { "systems": {
"locked": { "locked": {
"lastModified": 1653893745, "lastModified": 1681028828,
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=", "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "numtide", "owner": "nix-systems",
"repo": "flake-utils", "repo": "default",
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1", "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "numtide", "owner": "nix-systems",
"repo": "flake-utils", "repo": "default",
"type": "github" "type": "github"
} }
} }

View file

@ -3,20 +3,25 @@
inputs = { inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = {self, nixpkgs, utils}: outputs = { self, nixpkgs, flake-utils }:
let out = system: let
let pkgs = nixpkgs.legacyPackages."${system}"; out = system:
in { let pkgs = import nixpkgs { inherit system; };
devShell = pkgs.mkShell { in {
buildInputs = with pkgs; [ devShells.default = pkgs.mkShell {
gnumake buildInputs = with pkgs; [
nodePackages.sass nodejs_22
]; gnumake
nodePackages.pnpm
nodePackages.typescript-language-server # typescript
nodePackages.vscode-langservers-extracted # html, css, json, eslint
];
};
}; };
}; in
in with utils.lib; eachSystem defaultSystems out; flake-utils.lib.eachDefaultSystem out;
} }

View file

View file

@ -0,0 +1,7 @@
import { NonEmptyArray } from "../../../global.ts";
import { Technology } from "../domain/mod.ts";
import { AnyNode, TextNode } from "ren/node.ts";
export const TechnologyList: (techs: NonEmptyArray<Technology>) => AnyNode = (
techs,
) => new TextNode(techs.join(", "));

View file

@ -0,0 +1,7 @@
export enum Role {
Collaborator = "collaborator",
Author = "author",
TechLead = "tech&nbsp;lead",
TeamLead = "team&nbsp;lead",
Developer = "developer",
}

View file

@ -0,0 +1,25 @@
export enum Status {
// New features are being added and bugs are being fixed.
ActiveDeveloped = "actively-developed",
// There are no plans for new features, but the maintainer intends to respond
// to issues that get filed.
PassivelyMaintained = "passively-maintained",
// The package is feature complete, the maintainer does not intend to continue
// working on it or providing support, but it works for the purposes it was
// designed for.
AsIs = "as-is",
// The author wants to share it with the community but is not intending to
// meet anyone's particular use case.
Experimental = "experimental",
// The current maintainer would like to transfer the package to someone else.
LookingForMaintainer = "looking-for-maintainer",
// The maintainer does not recommend using this package (the description of the
// package can describe why, there could be a better solution available or
// there could be problems with the package that the author does not want to fix).
Deprecated = "deprecated",
}

View file

@ -0,0 +1,25 @@
export enum Technology {
C = "C",
JavaScript = "JS",
TypeScript = "TS",
Rust = "Rust",
Python = "Python",
Php = "PHP",
Deno = "Deno",
NodeJS = "NodeJS",
Flask = "Flask",
React = "React",
Antd = "Antd",
Postgresql = "PostgreSQL",
Docker = "Docker",
Drone = "Drone CI",
Woodpecker = "Woodpecker CI",
Bash = "Bash",
TreeSitter = "TreeSitter",
Nix = "Nix",
Lua = "Lua",
Sqlite = "Sqlite",
Vue = "Vue",
Godot = "Godot",
Haskell = "Haskell",
}

View file

@ -0,0 +1,5 @@
export { Role } from "./Role.ts";
export { Status } from "./Status.ts";
export { Technology } from "./Technology.ts";
export type { Work } from "./Work.ts";
export * as work from "./Work.ts";

36
package.json Normal file
View file

@ -0,0 +1,36 @@
{
"name": "pleshevskiy",
"version": "0.0.1",
"description": "Dmitriy Pleshevskiy",
"license": "MIT",
"type": "module",
"scripts": {
"docs:build": "vuepress build docs",
"docs:clean-dev": "vuepress dev docs --clean-cache",
"docs:dev": "vuepress dev docs",
"docs:update-package": "pnpm dlx vp-update"
},
"devDependencies": {
"@vuepress/bundler-vite": "^2.0.0-rc.7",
"@vuepress/plugin-blog": "^2.0.0-rc.11",
"@vuepress/plugin-redirect": "2.0.0-rc.8",
"@vuepress/theme-default": "^2.0.0-rc.11",
"vue": "^3.4.0",
"vuepress": "^2.0.0-rc.7",
"@rushstack/eslint-patch": "^1.1.4",
"@types/node": "^20.14.2",
"@vitejs/plugin-vue": "^4.0.0",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/language-server": "^2.0.19",
"@vue/tsconfig": "^0.5.1",
"@vue/typescript-plugin": "^2.0.19",
"eslint": "<9.0.0",
"eslint-plugin-cypress": "^3.3.0",
"eslint-plugin-vue": "^9.14.1",
"prettier": ">=3.0.0",
"typescript": "~5.4.5",
"vue-tsc": "^1.6.0"
}
}

4554
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load diff

11
tsconfig.json Normal file
View file

@ -0,0 +1,11 @@
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "docs/**/*", "docs/**/*.vue"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["./docs/*"]
}
}
}